vaspera-pm 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +24400 -0
- package/dist/cli.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +21353 -0
- package/dist/server.js.map +1 -0
- package/package.json +62 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/shared/src/types/index.ts","../../../packages/shared/src/errors/codes.ts","../../../packages/shared/src/errors/factory.ts","../../../packages/shared/src/utils/api-key.ts","../../../packages/shared/src/utils/encryption.ts","../../../packages/shared/src/ai/models.ts","../src/middleware/auth.ts","../src/middleware/usage.ts","../src/middleware/rate-limit.ts","../src/tools/plugin-loader.ts","../src/tools/types.ts","../src/ai/types.ts","../src/ai/client.ts","../src/output/folder-manager.ts","../src/output/metadata.ts","../src/tracking/cache-manager.ts","../src/tracking/audit-log.ts","../src/tracking/diff-engine.ts","../src/output/save-output.ts","../src/output/exporters/types.ts","../src/output/exporters/ado.ts","../src/output/exporters/jira.ts","../src/output/exporters/linear.ts","../src/output/exporters/github.ts","../src/output/exporters/index.ts","../src/output/index.ts","../src/tools/explode-backlog.ts","../src/tools/infer-prd.ts","../src/tools/synthesize-prd.ts","../src/tools/generate-architecture.ts","../src/tools/handoff-package.ts","../src/tools/synthesize-requirements.ts","../src/tools/review-prd.ts","../src/utils/csv-generator.ts","../src/utils/index.ts","../src/tools/sync-to-tracker/formatters/csv-formatter.ts","../src/tools/sync-to-tracker/formatters/markdown-formatter.ts","../src/tools/sync-to-tracker/formatters/import-instructions.ts","../src/tools/sync-to-tracker/formatters/index.ts","../src/tools/sync-to-tracker/config/platform-config.ts","../src/tools/sync-to-tracker/config/index.ts","../src/tools/sync-to-tracker/parsers/estimate-parser.ts","../src/tools/sync-to-tracker/parsers/priority-normalizer.ts","../src/tools/sync-to-tracker/parsers/index.ts","../src/tools/sync-to-tracker/index.ts","../src/tools/sync-to-tracker.ts","../src/tools/reverse-engineer-flows.ts","../src/tools/reverse-engineer-frontend.ts","../src/tools/generate-test-specs.ts","../src/tools/explain-codebase.ts","../src/ast/types.ts","../src/ast/typescript-parser.ts","../src/ast/extractors/nextjs.ts","../src/ast/extractors/express.ts","../src/ast/index.ts","../src/tools/validate-implementation.ts","../src/tools/suggest-refactors.ts","../src/tools/generate-api-docs.ts","../src/tools/dependency-audit.ts","../src/tools/estimate-migration.ts","../src/agents/types.ts","../src/agents/base-agent.ts","../src/agents/discovery-agent.ts","../src/agents/analyzer-agent.ts","../src/knowledge-base/types.ts","../src/knowledge-base/anonymizer.ts","../src/knowledge-base/collector.ts","../src/knowledge-base/matcher.ts","../src/knowledge-base/index.ts","../src/marketplace/rules-registry.ts","../src/marketplace/index.ts","../src/git-analysis/types.ts","../src/git-analysis/git-history-analyzer.ts","../src/git-analysis/doc-freshness-analyzer.ts","../src/git-analysis/code-doc-sync-detector.ts","../src/git-analysis/index.ts","../src/calibration/types.ts","../src/calibration/calibration-tracker.ts","../src/calibration/confidence-calibrator.ts","../src/calibration/index.ts","../src/agents/validator-agent.ts","../src/embeddings/local-embeddings.ts","../src/embeddings/pre-screening.ts","../src/embeddings/index.ts","../src/agents/specialist/base-specialist.ts","../src/agents/specialist/security-agent.ts","../src/agents/specialist/api-contract-agent.ts","../src/agents/specialist/performance-agent.ts","../src/agents/specialist/compliance-agent.ts","../src/agents/specialist/index.ts","../src/agents/orchestrator-agent.ts","../src/agents/index.ts","../src/tools/verify-docs-code.ts","../src/benchmark/types.ts","../src/benchmark/dataset-loader.ts","../src/benchmark/evaluation/metrics.ts","../src/benchmark/evaluation/runner.ts","../src/benchmark/evaluation/index.ts","../src/benchmark/samples/default-samples.ts","../src/benchmark/samples/index.ts","../src/benchmark/index.ts","../src/tools/run-benchmark.ts","../src/tools/analyze-git-freshness.ts","../src/tools/export-requirements.ts","../src/tools/generate-complete-backlog.ts","../src/tools/generate-deployment-runbook.ts","../src/tracking/changelog-generator.ts","../src/tracking/index.ts","../src/tools/generate-changelog.ts","../src/tools/detect-regressions.ts","../src/tools/generate-sprint-report.ts","../src/tools/track-estimates.ts","../src/tools/get-audit-trail.ts","../src/tools/run-pipeline/types.ts","../src/tools/run-pipeline/executor.ts","../src/tools/run-pipeline/index.ts","../src/tools/index.ts","../src/server.ts","../src/discovery/index.ts","../src/verification/index.ts","../src/analyze/index.ts","../src/cli.ts"],"sourcesContent":["// Subscription Types\nexport type SubscriptionTier = 'free' | 'starter' | 'pro' | 'enterprise';\nexport type SubscriptionStatus = 'active' | 'canceled' | 'past_due' | 'trialing' | 'incomplete';\n\n// User Profile\nexport interface UserProfile {\n id: string;\n email: string;\n fullName: string | null;\n avatarUrl: string | null;\n subscriptionTier: SubscriptionTier;\n subscriptionStatus: SubscriptionStatus;\n stripeCustomerId: string | null;\n stripeSubscriptionId: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\n// API Key\nexport interface ApiKey {\n id: string;\n userId: string;\n name: string;\n keyPrefix: string;\n lastUsedAt: string | null;\n expiresAt: string | null;\n revokedAt: string | null;\n createdAt: string;\n}\n\nexport interface ApiKeyWithSecret extends Omit<ApiKey, 'revokedAt'> {\n key: string; // Full key (only shown once)\n}\n\n// Usage\nexport interface UsageEvent {\n id: string;\n userId: string;\n apiKeyId: string | null;\n toolName: string;\n tokensUsed: number;\n latencyMs: number | null;\n success: boolean;\n errorCode: string | null;\n requestId: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface UsageSummary {\n period: {\n start: string;\n end: string;\n };\n summary: {\n totalToolCalls: number;\n totalTokensUsed: number;\n quotaUsed: number;\n quotaLimit: number;\n quotaPercentage: number;\n };\n byTool: Array<{\n tool: string;\n calls: number;\n tokensUsed: number;\n avgLatencyMs: number;\n }>;\n}\n\n// Quota Limits by Tier (monthly tool calls)\nexport const QUOTA_LIMITS: Record<SubscriptionTier, number> = {\n free: 100,\n starter: 500,\n pro: 2500,\n enterprise: 999999, // Effectively unlimited\n};\n\nexport const RATE_LIMITS: Record<SubscriptionTier, { perMinute: number; perDay: number }> = {\n free: { perMinute: 10, perDay: 100 },\n starter: { perMinute: 30, perDay: 1000 },\n pro: { perMinute: 60, perDay: 5000 },\n enterprise: { perMinute: 120, perDay: 999999 },\n};\n\n// Integration Types\nexport type IntegrationProvider = 'jira' | 'linear' | 'github' | 'gitlab' | 'asana' | 'ado';\n\nexport interface IntegrationToken {\n id: string;\n userId: string;\n provider: IntegrationProvider;\n tokenType: string;\n expiresAt: string | null;\n scopes: string[] | null;\n providerUserId: string | null;\n providerEmail: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface IntegrationStatus {\n provider: IntegrationProvider;\n connected: boolean;\n connectedAt?: string;\n providerEmail?: string;\n scopes?: string[];\n metadata?: Record<string, unknown>;\n}\n\n// MCP Tool Types\nexport type McpToolName =\n | 'synthesize_requirements'\n | 'review_prd'\n | 'explode_backlog'\n | 'generate_architecture'\n | 'sync_to_tracker'\n | 'infer_prd_from_code'\n | 'reverse_engineer_user_flows'\n | 'generate_test_specs'\n | 'explain_codebase'\n | 'validate_implementation'\n | 'suggest_refactors'\n | 'generate_api_docs'\n | 'dependency_audit'\n | 'estimate_migration';\n\nexport interface McpToolResult<T = unknown> {\n content: Array<{\n type: 'text' | 'image' | 'resource';\n text?: string;\n data?: string;\n mimeType?: string;\n }>;\n data?: T;\n tokensUsed?: number;\n isError?: boolean;\n}\n\n// API Response Types\nexport interface ApiSuccessResponse<T> {\n success: true;\n data: T;\n meta?: {\n requestId: string;\n timestamp: string;\n };\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error: {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n docUrl?: string;\n };\n meta?: {\n requestId: string;\n timestamp: string;\n };\n}\n\nexport type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;\n\n// ============================================\n// VasperaPM Output & Tracker Types\n// ============================================\n\n// Work item types for tracker export\nexport type WorkItemType = 'epic' | 'feature' | 'story' | 'task' | 'bug' | 'subtask';\nexport type WorkItemPriority = 'critical' | 'high' | 'medium' | 'low';\nexport type AssigneeType = 'frontend' | 'backend' | 'fullstack' | 'design' | 'qa' | 'devops';\nexport type EstimateUnit = 'points' | 'hours' | 'days';\nexport type TargetPlatform = 'jira' | 'ado' | 'linear' | 'github' | 'asana' | 'notion';\n\n// Universal tracker item (platform-agnostic)\nexport interface TrackerItem {\n id: string; // Local reference ID (VPM-001)\n type: WorkItemType;\n title: string;\n description: string;\n acceptanceCriteria: string[];\n priority: WorkItemPriority;\n estimate?: {\n value: number;\n unit: EstimateUnit;\n };\n labels: string[];\n parentId?: string; // Reference to parent item\n dependencies: string[]; // References to blocking items\n assigneeType?: AssigneeType;\n customFields?: Record<string, string>;\n}\n\n// Export package for tracker sync\nexport interface TrackerExportPackage {\n metadata: {\n tool: string;\n version: string;\n generated: string;\n sourceFile?: string;\n };\n targetPlatform: TargetPlatform;\n projectKey: string;\n items: TrackerItem[];\n hierarchy: {\n epics: string[];\n epicToFeatures: Record<string, string[]>;\n featureToStories: Record<string, string[]>;\n storyToTasks: Record<string, string[]>;\n };\n}\n\n// VasperaPM output folder structure\nexport type OutputCategory =\n | 'requirements'\n | 'prd'\n | 'backlog'\n | 'architecture'\n | 'test-specs'\n | 'code-analysis'\n | 'api'\n | 'handoff'\n | 'changelog';\n\n// Metadata header for generated files\nexport interface VasperaPMFileMetadata {\n tool: string;\n version: string;\n generated: string;\n inputs?: string[];\n tokensUsed?: number;\n status: 'complete' | 'partial' | 'error';\n fileVersion: string; // e.g., \"1.0\", \"1.1\"\n}\n\n// Output folder configuration\nexport interface VasperaPMConfig {\n outputPath: string; // Resolved output folder path\n projectName?: string;\n defaultPlatform?: TargetPlatform;\n fileVersioning: 'semantic' | 'date' | 'overwrite';\n}\n\n// ============================================\n// Standardized Tool Output Schema (Phase 1)\n// ============================================\n\n/**\n * Category of backlog items that can be extracted from tool outputs\n */\nexport type BacklogCategory =\n | 'feature' // From PRD, requirements\n | 'api' // From generate_api_docs\n | 'infrastructure' // From generate_architecture\n | 'testing' // From generate_test_specs\n | 'tech-debt' // From suggest_refactors\n | 'security' // From dependency_audit\n | 'frontend' // From reverse_engineer_user_flows\n | 'documentation' // From any docs changes\n | 'deployment'; // From generate_deployment_runbook\n\n/**\n * A backlog-ready item that can be extracted from any tool output\n */\nexport interface BacklogReadyItem {\n category: BacklogCategory;\n suggestedType: WorkItemType;\n title: string;\n description: string;\n acceptanceCriteria?: string[];\n priority: WorkItemPriority;\n estimate?: {\n value: number;\n unit: EstimateUnit;\n confidence: 'low' | 'medium' | 'high';\n };\n labels: string[];\n parentRef?: string; // Reference to parent item (title or ID)\n dependencies?: string[]; // Items this depends on\n assigneeType?: AssigneeType;\n source: {\n tool: string; // Tool that generated this\n section?: string; // Section of the document\n lineRef?: string; // Line reference in source\n };\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Standard format for tool outputs that support backlog extraction\n *\n * Tools implementing this interface can be consumed by generate_complete_backlog\n */\nexport interface BacklogExtractableOutput {\n /**\n * Metadata about the generation\n */\n metadata: VasperaPMFileMetadata;\n\n /**\n * Human-readable document content (markdown)\n */\n document: string;\n\n /**\n * Structured backlog items extracted from the document\n * This is populated when forBacklog=true\n */\n backlogItems?: BacklogReadyItem[];\n\n /**\n * Summary statistics\n */\n summary?: {\n totalItems: number;\n byCategory: Record<BacklogCategory, number>;\n byPriority: Record<WorkItemPriority, number>;\n estimatedEffort?: {\n totalPoints?: number;\n totalHours?: number;\n };\n };\n}\n\n/**\n * Options for backlog extraction in tool inputs\n */\nexport interface ForBacklogOptions {\n /**\n * Enable backlog item extraction\n */\n enabled: boolean;\n\n /**\n * Categories to extract (defaults to all applicable)\n */\n categories?: BacklogCategory[];\n\n /**\n * Include detailed acceptance criteria\n */\n includeAcceptanceCriteria?: boolean;\n\n /**\n * Include effort estimates\n */\n includeEstimates?: boolean;\n\n /**\n * Minimum priority to include (defaults to 'low')\n */\n minPriority?: WorkItemPriority;\n}\n","export interface ErrorDefinition {\n code: string;\n message: string;\n httpStatus: number;\n}\n\nexport const ErrorCodes = {\n // Authentication Errors (VPM-AUTH-XXX)\n AUTH: {\n REQUIRED: {\n code: 'VPM-AUTH-001',\n message: 'Authentication required',\n httpStatus: 401,\n },\n INVALID_TOKEN: {\n code: 'VPM-AUTH-002',\n message: 'Invalid or expired authentication token',\n httpStatus: 401,\n },\n INSUFFICIENT_PERMISSIONS: {\n code: 'VPM-AUTH-003',\n message: 'Insufficient permissions for this action',\n httpStatus: 403,\n },\n SESSION_EXPIRED: {\n code: 'VPM-AUTH-004',\n message: 'Session has expired, please login again',\n httpStatus: 401,\n },\n MFA_REQUIRED: {\n code: 'VPM-AUTH-005',\n message: 'Multi-factor authentication required',\n httpStatus: 403,\n },\n },\n\n // API Key Errors (VPM-API-KEY-XXX)\n API_KEY: {\n REQUIRED: {\n code: 'VPM-API-KEY-001',\n message: 'API key is required',\n httpStatus: 401,\n },\n INVALID: {\n code: 'VPM-API-KEY-002',\n message: 'Invalid API key',\n httpStatus: 401,\n },\n REVOKED: {\n code: 'VPM-API-KEY-003',\n message: 'API key has been revoked',\n httpStatus: 401,\n },\n EXPIRED: {\n code: 'VPM-API-KEY-004',\n message: 'API key has expired',\n httpStatus: 401,\n },\n RATE_LIMITED: {\n code: 'VPM-API-KEY-005',\n message: 'API key rate limit exceeded',\n httpStatus: 429,\n },\n QUOTA_EXCEEDED: {\n code: 'VPM-API-KEY-006',\n message: 'Monthly usage quota exceeded',\n httpStatus: 429,\n },\n },\n\n // MCP Tool Errors (VPM-MCP-XXX)\n MCP: {\n TOOL_NOT_FOUND: {\n code: 'VPM-MCP-001',\n message: 'Requested tool not found',\n httpStatus: 404,\n },\n INVALID_ARGUMENTS: {\n code: 'VPM-MCP-002',\n message: 'Invalid tool arguments provided',\n httpStatus: 400,\n },\n EXECUTION_FAILED: {\n code: 'VPM-MCP-003',\n message: 'Tool execution failed',\n httpStatus: 500,\n },\n TIMEOUT: {\n code: 'VPM-MCP-004',\n message: 'Tool execution timed out',\n httpStatus: 504,\n },\n LLM_ERROR: {\n code: 'VPM-MCP-005',\n message: 'AI model returned an error',\n httpStatus: 502,\n },\n CONTEXT_TOO_LARGE: {\n code: 'VPM-MCP-006',\n message: 'Input context exceeds maximum size',\n httpStatus: 413,\n },\n },\n\n // Billing Errors (VPM-BILLING-XXX)\n BILLING: {\n NO_SUBSCRIPTION: {\n code: 'VPM-BILLING-001',\n message: 'No active subscription found',\n httpStatus: 402,\n },\n SUBSCRIPTION_EXPIRED: {\n code: 'VPM-BILLING-002',\n message: 'Subscription has expired',\n httpStatus: 402,\n },\n PAYMENT_FAILED: {\n code: 'VPM-BILLING-003',\n message: 'Payment processing failed',\n httpStatus: 402,\n },\n FEATURE_NOT_INCLUDED: {\n code: 'VPM-BILLING-004',\n message: 'Feature not included in current plan',\n httpStatus: 403,\n },\n UPGRADE_REQUIRED: {\n code: 'VPM-BILLING-005',\n message: 'Plan upgrade required for this action',\n httpStatus: 403,\n },\n },\n\n // Integration Errors (VPM-INT-XXX)\n INTEGRATION: {\n NOT_CONNECTED: {\n code: 'VPM-INT-001',\n message: 'Integration not connected',\n httpStatus: 400,\n },\n TOKEN_EXPIRED: {\n code: 'VPM-INT-002',\n message: 'Integration token expired, reconnection required',\n httpStatus: 401,\n },\n REFRESH_FAILED: {\n code: 'VPM-INT-003',\n message: 'Failed to refresh integration token',\n httpStatus: 502,\n },\n API_ERROR: {\n code: 'VPM-INT-004',\n message: 'External integration API error',\n httpStatus: 502,\n },\n RATE_LIMITED: {\n code: 'VPM-INT-005',\n message: 'Integration rate limit exceeded',\n httpStatus: 429,\n },\n },\n\n // Validation Errors (VPM-VAL-XXX)\n VALIDATION: {\n REQUIRED_FIELD: {\n code: 'VPM-VAL-001',\n message: 'Required field missing',\n httpStatus: 400,\n },\n INVALID_FORMAT: {\n code: 'VPM-VAL-002',\n message: 'Invalid field format',\n httpStatus: 400,\n },\n OUT_OF_RANGE: {\n code: 'VPM-VAL-003',\n message: 'Value out of allowed range',\n httpStatus: 400,\n },\n INVALID_JSON: {\n code: 'VPM-VAL-004',\n message: 'Invalid JSON in request body',\n httpStatus: 400,\n },\n },\n\n // System Errors (VPM-SYS-XXX)\n SYSTEM: {\n INTERNAL_ERROR: {\n code: 'VPM-SYS-001',\n message: 'Internal server error',\n httpStatus: 500,\n },\n DATABASE_ERROR: {\n code: 'VPM-SYS-002',\n message: 'Database operation failed',\n httpStatus: 500,\n },\n SERVICE_UNAVAILABLE: {\n code: 'VPM-SYS-003',\n message: 'Service temporarily unavailable',\n httpStatus: 503,\n },\n MAINTENANCE_MODE: {\n code: 'VPM-SYS-004',\n message: 'System is under maintenance',\n httpStatus: 503,\n },\n },\n} as const;\n\nexport type ErrorCodeType =\n (typeof ErrorCodes)[keyof typeof ErrorCodes][keyof (typeof ErrorCodes)[keyof typeof ErrorCodes]];\n","import type { ErrorDefinition } from './codes.js';\nimport { ErrorCodes } from './codes.js';\n\nexport interface VasperaError {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n timestamp: string;\n requestId: string;\n docUrl?: string;\n}\n\nexport interface ErrorResponse {\n success: false;\n error: VasperaError;\n}\n\nfunction generateRequestId(): string {\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\nexport function createError(\n errorDef: ErrorDefinition,\n details?: Record<string, unknown>,\n requestId?: string\n): VasperaError {\n return {\n code: errorDef.code,\n message: errorDef.message,\n details,\n timestamp: new Date().toISOString(),\n requestId: requestId || generateRequestId(),\n docUrl: `https://docs.vaspera.pm/errors/${errorDef.code}`,\n };\n}\n\nexport function createErrorResponse(\n errorDef: ErrorDefinition,\n details?: Record<string, unknown>,\n requestId?: string\n): { response: ErrorResponse; status: number } {\n return {\n response: {\n success: false,\n error: createError(errorDef, details, requestId),\n },\n status: errorDef.httpStatus,\n };\n}\n\nfunction getNextResetDate(): string {\n const now = new Date();\n const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n return nextMonth.toISOString();\n}\n\n// Pre-built error creators for common cases\nexport const Errors = {\n authRequired: (requestId?: string) =>\n createErrorResponse(ErrorCodes.AUTH.REQUIRED, undefined, requestId),\n\n invalidApiKey: (requestId?: string) =>\n createErrorResponse(ErrorCodes.API_KEY.INVALID, undefined, requestId),\n\n apiKeyRevoked: (requestId?: string) =>\n createErrorResponse(ErrorCodes.API_KEY.REVOKED, undefined, requestId),\n\n apiKeyExpired: (requestId?: string) =>\n createErrorResponse(ErrorCodes.API_KEY.EXPIRED, undefined, requestId),\n\n rateLimited: (retryAfter: number, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.API_KEY.RATE_LIMITED,\n { retryAfterSeconds: retryAfter },\n requestId\n ),\n\n quotaExceeded: (currentUsage: number, limit: number, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.API_KEY.QUOTA_EXCEEDED,\n { currentUsage, limit, resetDate: getNextResetDate() },\n requestId\n ),\n\n toolNotFound: (toolName: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.MCP.TOOL_NOT_FOUND,\n { tool: toolName },\n requestId\n ),\n\n toolExecutionFailed: (toolName: string, reason: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.MCP.EXECUTION_FAILED,\n { tool: toolName, reason },\n requestId\n ),\n\n toolTimeout: (toolName: string, timeoutMs: number, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.MCP.TIMEOUT,\n { tool: toolName, timeoutMs },\n requestId\n ),\n\n validationFailed: (field: string, reason: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.VALIDATION.REQUIRED_FIELD,\n { field, reason },\n requestId\n ),\n\n invalidFormat: (field: string, expected: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.VALIDATION.INVALID_FORMAT,\n { field, expected },\n requestId\n ),\n\n internalError: (message?: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.SYSTEM.INTERNAL_ERROR,\n message ? { message } : undefined,\n requestId\n ),\n\n databaseError: (operation: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.SYSTEM.DATABASE_ERROR,\n { operation },\n requestId\n ),\n\n integrationNotConnected: (provider: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.INTEGRATION.NOT_CONNECTED,\n { provider },\n requestId\n ),\n\n subscriptionRequired: (feature: string, requiredTier: string, requestId?: string) =>\n createErrorResponse(\n ErrorCodes.BILLING.FEATURE_NOT_INCLUDED,\n { feature, requiredTier },\n requestId\n ),\n};\n\n// Custom error class for throwing in API routes\nexport class VasperaApiError extends Error {\n public readonly errorDef: ErrorDefinition;\n public readonly details?: Record<string, unknown>;\n\n constructor(errorDef: ErrorDefinition, details?: Record<string, unknown>) {\n super(errorDef.message);\n this.name = 'VasperaApiError';\n this.errorDef = errorDef;\n this.details = details;\n }\n\n toResponse(requestId?: string): { response: ErrorResponse; status: number } {\n return createErrorResponse(this.errorDef, this.details, requestId);\n }\n}\n","import { randomBytes, createHash } from 'crypto';\n\nconst API_KEY_PREFIX_LIVE = 'vpm_live_';\nconst API_KEY_PREFIX_TEST = 'vpm_test_';\nconst API_KEY_RANDOM_BYTES = 24; // 32 chars in base64url\n\nexport interface GeneratedApiKey {\n key: string; // Full key to show user once\n keyPrefix: string; // First 16 chars for identification\n keyHash: string; // Hash for storage and validation\n}\n\n/**\n * Generate a new API key\n * @param environment - 'live' or 'test'\n * @returns Generated key with prefix and hash\n */\nexport function generateApiKey(environment: 'live' | 'test' = 'live'): GeneratedApiKey {\n const prefix = environment === 'live' ? API_KEY_PREFIX_LIVE : API_KEY_PREFIX_TEST;\n const randomPart = randomBytes(API_KEY_RANDOM_BYTES)\n .toString('base64url')\n .slice(0, 32);\n\n const key = `${prefix}${randomPart}`;\n const keyPrefix = key.slice(0, 16);\n const keyHash = hashApiKey(key);\n\n return {\n key,\n keyPrefix,\n keyHash,\n };\n}\n\n/**\n * Hash an API key for storage\n * Using SHA-256 since we need to look up by hash\n */\nexport function hashApiKey(key: string): string {\n return createHash('sha256').update(key).digest('hex');\n}\n\n/**\n * Validate API key format\n */\nexport function isValidApiKeyFormat(key: string): boolean {\n const livePattern = /^vpm_live_[a-zA-Z0-9_-]{32}$/;\n const testPattern = /^vpm_test_[a-zA-Z0-9_-]{32}$/;\n return livePattern.test(key) || testPattern.test(key);\n}\n\n/**\n * Extract prefix from API key\n */\nexport function extractKeyPrefix(key: string): string {\n return key.slice(0, 16);\n}\n\n/**\n * Check if key is a test key\n */\nexport function isTestKey(key: string): boolean {\n return key.startsWith(API_KEY_PREFIX_TEST);\n}\n\n/**\n * Mask an API key for display (show first 16 and last 4 chars)\n */\nexport function maskApiKey(key: string): string {\n if (key.length < 24) return key;\n return `${key.slice(0, 16)}...${key.slice(-4)}`;\n}\n","import {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n scrypt,\n} from 'crypto';\nimport { promisify } from 'util';\n\nconst scryptAsync = promisify(scrypt);\nconst ALGORITHM = 'aes-256-gcm';\nconst IV_LENGTH = 16;\nconst SALT_LENGTH = 32;\nconst TAG_LENGTH = 16;\nconst KEY_LENGTH = 32;\n\n/**\n * Encrypt text using AES-256-GCM\n * @param text - Plain text to encrypt\n * @param secret - Encryption secret\n * @returns Encrypted string in format: salt:iv:tag:ciphertext (all base64)\n */\nexport async function encrypt(text: string, secret: string): Promise<string> {\n const salt = randomBytes(SALT_LENGTH);\n const iv = randomBytes(IV_LENGTH);\n const key = (await scryptAsync(secret, salt, KEY_LENGTH)) as Buffer;\n\n const cipher = createCipheriv(ALGORITHM, key, iv);\n const encrypted = Buffer.concat([\n cipher.update(text, 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n\n // Format: salt:iv:tag:encrypted (all base64)\n return [\n salt.toString('base64'),\n iv.toString('base64'),\n tag.toString('base64'),\n encrypted.toString('base64'),\n ].join(':');\n}\n\n/**\n * Decrypt text that was encrypted with encrypt()\n * @param encryptedText - Encrypted string in format: salt:iv:tag:ciphertext\n * @param secret - Encryption secret (must match encryption)\n * @returns Decrypted plain text\n */\nexport async function decrypt(\n encryptedText: string,\n secret: string\n): Promise<string> {\n const parts = encryptedText.split(':');\n if (parts.length !== 4) {\n throw new Error('Invalid encrypted text format');\n }\n\n const [saltB64, ivB64, tagB64, encryptedB64] = parts;\n\n const salt = Buffer.from(saltB64!, 'base64');\n const iv = Buffer.from(ivB64!, 'base64');\n const tag = Buffer.from(tagB64!, 'base64');\n const encrypted = Buffer.from(encryptedB64!, 'base64');\n\n const key = (await scryptAsync(secret, salt, KEY_LENGTH)) as Buffer;\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(tag);\n\n return decipher.update(encrypted) + decipher.final('utf8');\n}\n\n/**\n * Generate a random encryption secret\n * @returns 32-byte hex string suitable for use as encryption secret\n */\nexport function generateEncryptionSecret(): string {\n return randomBytes(32).toString('hex');\n}\n","/**\n * Centralized AI Model Configuration (TD-005)\n *\n * Single source of truth for all AI model constants across VasperaPM.\n * Update model versions here and they propagate everywhere.\n */\n\n// ============================================================================\n// Model IDs\n// ============================================================================\n\n/**\n * Current Claude model versions\n * Update these when new model versions are released\n */\nexport const MODEL_IDS = {\n CLAUDE_SONNET: 'claude-sonnet-4-20250514',\n CLAUDE_HAIKU: 'claude-3-5-haiku-20241022',\n CLAUDE_OPUS: 'claude-3-opus-20240229', // Future-proofing\n} as const;\n\nexport type ModelId = (typeof MODEL_IDS)[keyof typeof MODEL_IDS];\n\n// ============================================================================\n// Model Capabilities\n// ============================================================================\n\n/**\n * Model tiers for different use cases\n */\nexport const MODEL_TIERS = {\n /** Fast responses, lower cost - good for simple tasks */\n fast: MODEL_IDS.CLAUDE_HAIKU,\n /** Balanced speed and quality - default for most tasks */\n balanced: MODEL_IDS.CLAUDE_SONNET,\n /** Best quality for complex reasoning */\n powerful: MODEL_IDS.CLAUDE_SONNET,\n} as const;\n\nexport type ModelTier = keyof typeof MODEL_TIERS;\n\n/**\n * Default models for different contexts\n */\nexport const DEFAULT_MODELS = {\n /** Default for general VasperaPM tools */\n default: MODEL_IDS.CLAUDE_SONNET,\n /** For quick responses where quality is less critical */\n fast: MODEL_IDS.CLAUDE_HAIKU,\n /** For complex analysis tasks */\n analysis: MODEL_IDS.CLAUDE_SONNET,\n /** For code generation */\n codeGen: MODEL_IDS.CLAUDE_SONNET,\n} as const;\n\n// ============================================================================\n// Token Limits\n// ============================================================================\n\n/**\n * Token limits per model\n * Keep in sync with Anthropic's published limits\n */\nexport const MODEL_LIMITS = {\n [MODEL_IDS.CLAUDE_SONNET]: {\n maxInputTokens: 200000,\n maxOutputTokens: 64000,\n contextWindow: 200000,\n },\n [MODEL_IDS.CLAUDE_HAIKU]: {\n maxInputTokens: 200000,\n maxOutputTokens: 8192,\n contextWindow: 200000,\n },\n [MODEL_IDS.CLAUDE_OPUS]: {\n maxInputTokens: 200000,\n maxOutputTokens: 4096,\n contextWindow: 200000,\n },\n} as const;\n\nexport type ModelLimits = (typeof MODEL_LIMITS)[ModelId];\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get the model ID for a given tier\n */\nexport function getModelForTier(tier: ModelTier): ModelId {\n return MODEL_TIERS[tier];\n}\n\n/**\n * Get token limits for a model\n */\nexport function getModelLimits(modelId: ModelId): ModelLimits {\n return MODEL_LIMITS[modelId];\n}\n\n/**\n * Check if a string is a valid model ID\n */\nexport function isValidModelId(id: string): id is ModelId {\n return Object.values(MODEL_IDS).includes(id as ModelId);\n}\n\n/**\n * Get display name for a model\n */\nexport function getModelDisplayName(modelId: ModelId): string {\n switch (modelId) {\n case MODEL_IDS.CLAUDE_SONNET:\n return 'Claude Sonnet';\n case MODEL_IDS.CLAUDE_HAIKU:\n return 'Claude Haiku';\n case MODEL_IDS.CLAUDE_OPUS:\n return 'Claude Opus';\n default:\n return modelId;\n }\n}\n\n// ============================================================================\n// Backward Compatibility Aliases\n// ============================================================================\n\n/**\n * @deprecated Use MODEL_IDS directly\n */\nexport const MODELS = MODEL_IDS;\n\n/**\n * @deprecated Use DEFAULT_MODELS.default\n */\nexport const DEFAULT_MODEL = DEFAULT_MODELS.default;\n\n/**\n * @deprecated Use DEFAULT_MODELS.fast\n */\nexport const FAST_MODEL = DEFAULT_MODELS.fast;\n","import { createHash } from 'crypto';\nimport { QUOTA_LIMITS, type SubscriptionTier } from '@vaspera/shared';\n\n// Response type from validate-key API\ninterface ValidateKeyResponse {\n valid: boolean;\n user?: {\n id: string;\n email: string;\n subscriptionTier: string;\n };\n key?: {\n id: string;\n scopes: string[];\n };\n quota?: {\n limit: number;\n used: number;\n remaining: number;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\nexport interface ValidationResult {\n valid: boolean;\n userId?: string;\n apiKeyId?: string;\n tier?: SubscriptionTier;\n scopes?: string[];\n quota?: {\n limit: number;\n used: number;\n remaining: number;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n// API endpoint for validation (configured via environment)\nconst VALIDATE_KEY_URL = process.env.VASPERA_API_URL || 'https://vaspera.dev';\n\n// Local Supabase URL for development\nconst SUPABASE_URL = process.env.SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL || 'http://127.0.0.1:54321';\nconst SUPABASE_SERVICE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || '';\n\n/**\n * Validate API key against local Supabase (for development)\n */\nasync function validateLocalApiKey(apiKey: string): Promise<ValidationResult> {\n if (!SUPABASE_SERVICE_KEY) {\n throw new Error('SUPABASE_SERVICE_ROLE_KEY not configured for local validation');\n }\n\n const keyPrefix = apiKey.slice(0, 16);\n const keyHash = createHash('sha256').update(apiKey).digest('hex');\n\n // Query Supabase directly\n const response = await fetch(`${SUPABASE_URL}/rest/v1/rpc/validate_api_key`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_SERVICE_KEY,\n 'Authorization': `Bearer ${SUPABASE_SERVICE_KEY}`,\n },\n body: JSON.stringify({ p_key_prefix: keyPrefix }),\n });\n\n if (!response.ok) {\n throw new Error(`Local validation failed: ${response.status}`);\n }\n\n const results = await response.json() as Array<{\n is_valid: boolean;\n user_id: string | null;\n key_id: string | null;\n subscription_tier: string | null;\n error_code: string | null;\n }>;\n\n const result = results[0];\n\n if (!result?.is_valid) {\n return {\n valid: false,\n error: {\n code: result?.error_code || 'VPM-API-KEY-002',\n message: 'Invalid API key',\n },\n };\n }\n\n // Get quota info\n const quotaResponse = await fetch(`${SUPABASE_URL}/rest/v1/rpc/check_usage_quota`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_SERVICE_KEY,\n 'Authorization': `Bearer ${SUPABASE_SERVICE_KEY}`,\n },\n body: JSON.stringify({ p_user_id: result.user_id }),\n });\n\n let quota = { limit: QUOTA_LIMITS.enterprise, used: 0, remaining: QUOTA_LIMITS.enterprise };\n if (quotaResponse.ok) {\n const quotaResults = await quotaResponse.json() as Array<{\n quota_limit: number;\n quota_used: number;\n quota_remaining: number;\n }>;\n if (quotaResults[0]) {\n quota = {\n limit: quotaResults[0].quota_limit,\n used: quotaResults[0].quota_used,\n remaining: quotaResults[0].quota_remaining,\n };\n }\n }\n\n return {\n valid: true,\n userId: result.user_id!,\n apiKeyId: result.key_id!,\n tier: (result.subscription_tier as SubscriptionTier) || 'free',\n scopes: ['*'], // All scopes for local dev\n quota,\n };\n}\n\n/**\n * Validate an API key against the VasperaPM backend\n */\nexport async function validateApiKey(apiKey: string | undefined): Promise<ValidationResult> {\n // DEV MODE: Skip all validation when VASPERA_DEV_MODE=true\n // This allows local development without requiring API key validation\n if (process.env.VASPERA_DEV_MODE === 'true' || process.env.NODE_ENV === 'development') {\n // If a test key is provided, use it; otherwise use defaults\n if (!apiKey || !apiKey.startsWith('vpm_')) {\n console.log('[VasperaPM] Dev mode: Using default test credentials');\n return {\n valid: true,\n userId: 'dev-user',\n apiKeyId: 'dev-key',\n tier: 'pro',\n scopes: ['*'],\n quota: {\n limit: QUOTA_LIMITS.pro,\n used: 0,\n remaining: QUOTA_LIMITS.pro,\n },\n };\n }\n }\n\n if (!apiKey) {\n return {\n valid: false,\n error: {\n code: 'VPM-API-KEY-001',\n message: 'API key is required. Set VASPERA_API_KEY environment variable.',\n },\n };\n }\n\n // Validate key format\n if (!apiKey.startsWith('vpm_live_') && !apiKey.startsWith('vpm_test_')) {\n return {\n valid: false,\n error: {\n code: 'VPM-API-KEY-002',\n message: 'Invalid API key format. Keys must start with vpm_live_ or vpm_test_',\n },\n };\n }\n\n try {\n const response = await fetch(`${VALIDATE_KEY_URL}/api/validate-key`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ apiKey }),\n });\n\n const data = (await response.json()) as ValidateKeyResponse;\n\n if (!response.ok || !data.valid) {\n return {\n valid: false,\n error: data.error || {\n code: 'VPM-API-KEY-002',\n message: 'Invalid API key',\n },\n };\n }\n\n return {\n valid: true,\n userId: data.user?.id,\n apiKeyId: data.key?.id,\n tier: data.user?.subscriptionTier as SubscriptionTier,\n scopes: data.key?.scopes || [],\n quota: data.quota,\n };\n } catch (error) {\n console.error('API key validation error:', error);\n\n // Fall back to local Supabase validation in development\n if (process.env.NODE_ENV === 'development' && SUPABASE_SERVICE_KEY) {\n try {\n console.error('Using local Supabase validation');\n return await validateLocalApiKey(apiKey);\n } catch (localError) {\n console.error('Local validation also failed:', localError);\n }\n }\n\n // Fall back to offline validation for test keys in development\n if (process.env.NODE_ENV === 'development' && apiKey.startsWith('vpm_test_')) {\n console.error('Using offline test mode');\n return {\n valid: true,\n userId: 'test-user',\n apiKeyId: 'test-key',\n tier: 'free',\n scopes: ['*'],\n quota: {\n limit: QUOTA_LIMITS.free,\n used: 0,\n remaining: QUOTA_LIMITS.free,\n },\n };\n }\n\n return {\n valid: false,\n error: {\n code: 'VPM-INTERNAL-001',\n message: 'Failed to validate API key. Please try again.',\n },\n };\n }\n}\n\n/**\n * Check if a scope is allowed for the given validation result\n */\nexport function hasScope(validation: ValidationResult, requiredScope: string): boolean {\n if (!validation.valid || !validation.scopes) return false;\n return validation.scopes.includes('*') || validation.scopes.includes(requiredScope);\n}\n","export interface UsageEvent {\n userId: string;\n apiKeyId: string;\n toolName: string;\n tokensUsed: number;\n latencyMs: number;\n success: boolean;\n errorCode?: string;\n metadata?: Record<string, unknown>;\n}\n\n// API endpoint for usage tracking (configured via environment)\nconst USAGE_API_URL = process.env.VASPERA_API_URL || 'https://vaspera.dev';\nconst INTERNAL_SERVICE_KEY = process.env.INTERNAL_SERVICE_KEY;\n\n/**\n * Track a usage event to the VasperaPM backend\n */\nexport async function trackUsage(event: UsageEvent): Promise<void> {\n // Skip tracking if no service key configured\n if (!INTERNAL_SERVICE_KEY) {\n console.error('INTERNAL_SERVICE_KEY not configured, skipping usage tracking');\n return;\n }\n\n try {\n const response = await fetch(`${USAGE_API_URL}/api/usage`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${INTERNAL_SERVICE_KEY}`,\n },\n body: JSON.stringify({\n userId: event.userId,\n apiKeyId: event.apiKeyId,\n toolName: event.toolName,\n tokensUsed: event.tokensUsed,\n latencyMs: event.latencyMs,\n success: event.success,\n errorCode: event.errorCode,\n metadata: event.metadata,\n requestId: generateRequestId(),\n }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n console.error('Failed to track usage:', error);\n }\n } catch (error) {\n console.error('Usage tracking error:', error);\n // Don't throw - usage tracking should not fail the request\n }\n}\n\n/**\n * Generate a unique request ID for tracking\n */\nfunction generateRequestId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `req_${timestamp}_${random}`;\n}\n\n/**\n * Calculate approximate tokens from text\n * Uses a simple estimation of ~4 characters per token\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Calculate total tokens from input and output\n */\nexport function calculateTokens(input: string, output: string): number {\n return estimateTokens(input) + estimateTokens(output);\n}\n","import type { SubscriptionTier } from '@vaspera/shared';\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n limit: number;\n resetsAt?: Date;\n}\n\n// Rate limits per minute by tier\nconst RATE_LIMITS: Record<SubscriptionTier, number> = {\n free: 5, // 5 requests per minute\n starter: 20, // 20 requests per minute\n pro: 60, // 60 requests per minute (1 per second)\n enterprise: 300, // 300 requests per minute (5 per second)\n};\n\n// In-memory rate limit store (for single instance)\n// In production, use Redis or similar for distributed rate limiting\nconst rateLimitStore = new Map<string, { count: number; resetAt: number }>();\n\n// Cleanup old entries every minute\nsetInterval(() => {\n const now = Date.now();\n for (const [key, value] of rateLimitStore.entries()) {\n if (value.resetAt < now) {\n rateLimitStore.delete(key);\n }\n }\n}, 60000);\n\n/**\n * Check if a request is allowed under rate limits\n */\nexport async function checkRateLimit(\n userId: string,\n tier: SubscriptionTier\n): Promise<RateLimitResult> {\n const limit = RATE_LIMITS[tier] || RATE_LIMITS.free;\n const windowMs = 60000; // 1 minute window\n const now = Date.now();\n\n const key = `rate:${userId}`;\n let entry = rateLimitStore.get(key);\n\n // Initialize or reset if window expired\n if (!entry || entry.resetAt < now) {\n entry = {\n count: 0,\n resetAt: now + windowMs,\n };\n rateLimitStore.set(key, entry);\n }\n\n // Check if over limit\n if (entry.count >= limit) {\n return {\n allowed: false,\n remaining: 0,\n limit,\n resetsAt: new Date(entry.resetAt),\n };\n }\n\n // Increment counter\n entry.count++;\n rateLimitStore.set(key, entry);\n\n return {\n allowed: true,\n remaining: limit - entry.count,\n limit,\n resetsAt: new Date(entry.resetAt),\n };\n}\n\n/**\n * Reset rate limit for a user (e.g., after upgrade)\n */\nexport function resetRateLimit(userId: string): void {\n rateLimitStore.delete(`rate:${userId}`);\n}\n\n/**\n * Get current rate limit status without incrementing\n */\nexport function getRateLimitStatus(\n userId: string,\n tier: SubscriptionTier\n): RateLimitResult {\n const limit = RATE_LIMITS[tier] || RATE_LIMITS.free;\n const key = `rate:${userId}`;\n const entry = rateLimitStore.get(key);\n\n if (!entry || entry.resetAt < Date.now()) {\n return {\n allowed: true,\n remaining: limit,\n limit,\n };\n }\n\n return {\n allowed: entry.count < limit,\n remaining: Math.max(0, limit - entry.count),\n limit,\n resetsAt: new Date(entry.resetAt),\n };\n}\n","/**\n * Tool Plugin Loader\n *\n * Automatically discovers and loads tool definitions from the tools directory.\n * Eliminates the need for manual import/registration in index.ts.\n */\n\nimport { readdirSync, statSync } from 'fs';\nimport { join, basename } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition, ToolHandler } from './types.js';\n\n// Get the directory of this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Files to exclude from auto-discovery\n */\nconst EXCLUDED_FILES = new Set([\n 'index.ts',\n 'index.js',\n 'types.ts',\n 'types.js',\n 'plugin-loader.ts',\n 'plugin-loader.js',\n]);\n\n/**\n * Directories to exclude from auto-discovery\n */\nconst EXCLUDED_DIRS = new Set([\n 'sync-to-tracker', // This is a module directory, not a tool\n '__tests__',\n 'test',\n]);\n\n/**\n * Validation result for a tool\n */\ninterface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate that an object is a valid ToolDefinition\n */\nfunction validateToolDefinition(obj: unknown, filename: string): ValidationResult {\n const errors: string[] = [];\n\n if (!obj || typeof obj !== 'object') {\n return { valid: false, errors: ['Export is not an object'] };\n }\n\n const def = obj as Record<string, unknown>;\n\n // Check for tool property\n if (!def.tool) {\n errors.push('Missing \"tool\" property');\n } else {\n const tool = def.tool as Record<string, unknown>;\n if (!tool.name || typeof tool.name !== 'string') {\n errors.push('Missing or invalid \"tool.name\"');\n }\n if (!tool.description || typeof tool.description !== 'string') {\n errors.push('Missing or invalid \"tool.description\"');\n }\n if (!tool.inputSchema || typeof tool.inputSchema !== 'object') {\n errors.push('Missing or invalid \"tool.inputSchema\"');\n }\n }\n\n // Check for handler property\n if (!def.handler) {\n errors.push('Missing \"handler\" property');\n } else if (typeof def.handler !== 'function') {\n errors.push('\"handler\" is not a function');\n }\n\n if (errors.length > 0) {\n console.warn(`[PluginLoader] Validation errors in ${filename}:`, errors);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Find the exported ToolDefinition from a module\n *\n * Tools can export their definition as:\n * - Default export\n * - Named export ending in \"Tool\" (e.g., explodeBacklogTool)\n */\nfunction findToolDefinition(module: Record<string, unknown>, filename: string): ToolDefinition | null {\n // Try named exports first (look for *Tool pattern)\n for (const [key, value] of Object.entries(module)) {\n if (key.endsWith('Tool') && value && typeof value === 'object') {\n const validation = validateToolDefinition(value, filename);\n if (validation.valid) {\n return value as ToolDefinition;\n }\n }\n }\n\n // Try default export\n if (module.default) {\n const validation = validateToolDefinition(module.default, filename);\n if (validation.valid) {\n return module.default as ToolDefinition;\n }\n }\n\n return null;\n}\n\n/**\n * Discover tool files in the tools directory\n */\nfunction discoverToolFiles(toolsDir: string): string[] {\n const files: string[] = [];\n\n try {\n const entries = readdirSync(toolsDir);\n\n for (const entry of entries) {\n const fullPath = join(toolsDir, entry);\n const stat = statSync(fullPath);\n\n // Skip directories\n if (stat.isDirectory()) {\n if (!EXCLUDED_DIRS.has(entry)) {\n // Could recursively scan subdirs in the future\n }\n continue;\n }\n\n // Skip non-JS/TS files\n if (!entry.endsWith('.js') && !entry.endsWith('.ts')) {\n continue;\n }\n\n // Skip excluded files\n if (EXCLUDED_FILES.has(entry)) {\n continue;\n }\n\n // Skip .d.ts files\n if (entry.endsWith('.d.ts')) {\n continue;\n }\n\n // Skip test files\n if (entry.includes('.test.') || entry.includes('.spec.')) {\n continue;\n }\n\n files.push(entry);\n }\n } catch (err) {\n console.error('[PluginLoader] Error scanning tools directory:', err);\n }\n\n return files.sort();\n}\n\n/**\n * Load all tools from the tools directory\n *\n * This is an async function that dynamically imports tool modules\n */\nexport async function loadTools(): Promise<{\n tools: Tool[];\n toolHandlers: Record<string, ToolHandler>;\n toolDefinitions: ToolDefinition[];\n}> {\n const toolDefinitions: ToolDefinition[] = [];\n const toolsDir = __dirname;\n\n // In development, we work with .ts files\n // In production (built), we work with .js files\n const toolFiles = discoverToolFiles(toolsDir);\n\n console.log(`[PluginLoader] Discovered ${toolFiles.length} tool files`);\n\n for (const file of toolFiles) {\n try {\n // Convert .ts to .js for import (tsup compiles to .js)\n const importPath = `./${file.replace('.ts', '.js')}`;\n\n // Dynamic import\n const module = (await import(importPath)) as Record<string, unknown>;\n\n // Find the tool definition\n const toolDef = findToolDefinition(module, file);\n\n if (toolDef) {\n toolDefinitions.push(toolDef);\n console.log(`[PluginLoader] Loaded: ${toolDef.tool.name} from ${file}`);\n } else {\n console.warn(`[PluginLoader] No valid ToolDefinition found in ${file}`);\n }\n } catch (err) {\n console.error(`[PluginLoader] Error loading ${file}:`, err);\n }\n }\n\n // Build the tools array and handlers map\n const tools = toolDefinitions.map((t) => t.tool);\n const toolHandlers = Object.fromEntries(toolDefinitions.map((t) => [t.tool.name, t.handler]));\n\n console.log(`[PluginLoader] Successfully loaded ${toolDefinitions.length} tools`);\n\n return { tools, toolHandlers, toolDefinitions };\n}\n\n/**\n * Get tool names for validation\n */\nexport function getLoadedToolNames(toolDefinitions: ToolDefinition[]): string[] {\n return toolDefinitions.map((t) => t.tool.name);\n}\n\n/**\n * Validate that all required tools are loaded\n */\nexport function validateRequiredTools(\n toolDefinitions: ToolDefinition[],\n requiredTools: string[]\n): { valid: boolean; missing: string[] } {\n const loadedNames = new Set(getLoadedToolNames(toolDefinitions));\n const missing = requiredTools.filter((name) => !loadedNames.has(name));\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\n\n/**\n * Result returned by a tool handler\n */\nexport interface ToolResult {\n content: Array<{\n type: 'text';\n text: string;\n } | {\n type: 'resource';\n resource: {\n uri: string;\n mimeType: string;\n text?: string;\n blob?: string;\n };\n }>;\n tokensUsed?: number;\n isError?: boolean;\n}\n\n/**\n * Tool handler function signature\n */\nexport type ToolHandler = (\n args: Record<string, unknown>,\n validation: ValidationResult\n) => Promise<ToolResult>;\n\n/**\n * Tool definition with handler\n */\nexport interface ToolDefinition {\n tool: Tool;\n handler: ToolHandler;\n requiredScope?: string;\n}\n\n/**\n * Helper to create a text result\n */\nexport function textResult(text: string, tokensUsed?: number): ToolResult {\n return {\n content: [{ type: 'text', text }],\n tokensUsed,\n };\n}\n\n/**\n * Helper to create a JSON result\n */\nexport function jsonResult(data: unknown, tokensUsed?: number): ToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n tokensUsed,\n };\n}\n\n/**\n * Helper to create an error result\n */\nexport function errorResult(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `Error: ${message}` }],\n };\n}\n\n/**\n * Helper to create a markdown result\n */\nexport function markdownResult(markdown: string, tokensUsed?: number): ToolResult {\n return {\n content: [{ type: 'text', text: markdown }],\n tokensUsed,\n };\n}\n","/**\n * AI Client Type Definitions\n *\n * Interfaces for dependency injection and testability.\n */\n\nimport type { ModelTier } from '@vaspera/shared';\n\n// ============================================================================\n// Completion Types\n// ============================================================================\n\n/**\n * Options for creating a text completion\n */\nexport interface CompletionOptions {\n systemPrompt: string;\n userMessage: string;\n model?: ModelTier;\n maxTokens?: number;\n temperature?: number;\n /** Override default timeout for this request */\n timeout?: number;\n /** Override default max retries for this request */\n maxRetries?: number;\n}\n\n/**\n * Result from a text completion\n */\nexport interface CompletionResult {\n text: string;\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Options for creating a JSON completion\n */\nexport interface JsonCompletionOptions extends Omit<CompletionOptions, 'temperature'> {\n /** Optional: provide expected schema for better validation */\n expectedKeys?: string[];\n}\n\n/**\n * Result from a JSON completion\n */\nexport interface JsonCompletionResult<T> {\n data: T;\n inputTokens: number;\n outputTokens: number;\n}\n\n// ============================================================================\n// Chunked Completion Types\n// ============================================================================\n\n/**\n * Options for chunked completion processing\n */\nexport interface ChunkedCompletionOptions {\n systemPrompt: string;\n /** Array of content chunks to process */\n chunks: Array<{ id: string; content: string }>;\n /** Prompt template for each chunk. Use {{content}} and {{id}} placeholders */\n chunkPromptTemplate: string;\n model?: ModelTier;\n maxTokens?: number;\n /** Process chunks in parallel (default: false for rate limit safety) */\n parallel?: boolean;\n /** Max parallel requests (default: 3) */\n maxParallel?: number;\n /** Callback for progress updates */\n onProgress?: (completed: number, total: number, chunkId: string) => void;\n}\n\n/**\n * Result from chunked completion processing\n */\nexport interface ChunkedCompletionResult<T> {\n results: Array<{ id: string; data: T; inputTokens: number; outputTokens: number }>;\n totalInputTokens: number;\n totalOutputTokens: number;\n}\n\n// ============================================================================\n// AI Client Interface\n// ============================================================================\n\n/**\n * AI Client interface for dependency injection.\n *\n * Implementations must provide completion and JSON completion methods.\n * This enables testing with mock clients and swapping AI providers.\n */\nexport interface IAIClient {\n /**\n * Create a text completion\n */\n createCompletion(options: CompletionOptions): Promise<CompletionResult>;\n\n /**\n * Create a structured JSON completion\n */\n createJsonCompletion<T>(options: JsonCompletionOptions): Promise<JsonCompletionResult<T>>;\n\n /**\n * Process multiple chunks with individual AI calls\n */\n createChunkedCompletion<T>(options: ChunkedCompletionOptions): Promise<ChunkedCompletionResult<T>>;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * AI error codes for categorizing failures\n */\nexport type AIErrorCode =\n | 'TIMEOUT'\n | 'CONNECTION_ERROR'\n | 'RATE_LIMITED'\n | 'INVALID_API_KEY'\n | 'MODEL_OVERLOADED'\n | 'CONTENT_FILTERED'\n | 'TRUNCATED_RESPONSE'\n | 'INVALID_JSON'\n | 'UNKNOWN';\n\n/**\n * AI Client Configuration\n */\nexport interface AIClientConfig {\n /** Request timeout in milliseconds (default: 120000 = 2 minutes) */\n timeout: number;\n /** Maximum retry attempts for transient failures (default: 3) */\n maxRetries: number;\n /** Base delay for exponential backoff in ms (default: 1000) */\n retryBaseDelay: number;\n /** Maximum delay between retries in ms (default: 30000) */\n retryMaxDelay: number;\n}\n\n/**\n * Default AI client configuration\n */\nexport const DEFAULT_AI_CONFIG: AIClientConfig = {\n timeout: 120000, // 2 minutes per request\n maxRetries: 3, // Retry up to 3 times\n retryBaseDelay: 1000, // Start with 1 second delay\n retryMaxDelay: 30000, // Max 30 seconds between retries\n};\n","import Anthropic from '@anthropic-ai/sdk';\nimport {\n MODEL_IDS,\n MODEL_TIERS,\n DEFAULT_MODELS,\n getModelForTier,\n type ModelId,\n type ModelTier,\n} from '@vaspera/shared';\nimport type {\n IAIClient,\n AIClientConfig,\n CompletionOptions,\n CompletionResult,\n JsonCompletionOptions,\n JsonCompletionResult,\n ChunkedCompletionOptions,\n ChunkedCompletionResult,\n AIErrorCode,\n} from './types.js';\nimport { DEFAULT_AI_CONFIG } from './types.js';\n\n// Re-export model types for convenience\nexport { MODEL_IDS, MODEL_TIERS, DEFAULT_MODELS, getModelForTier };\nexport type { ModelId, ModelTier };\n\n// Re-export types from types.ts\nexport type {\n IAIClient,\n CompletionOptions,\n CompletionResult,\n JsonCompletionOptions,\n JsonCompletionResult,\n ChunkedCompletionOptions,\n ChunkedCompletionResult,\n AIClientConfig,\n AIErrorCode,\n};\n\n// ============================================================================\n// Error Handling\n// ============================================================================\n\n/**\n * Error types for AI operations\n */\nexport class AIError extends Error {\n constructor(\n message: string,\n public readonly code: AIErrorCode,\n public readonly retryable: boolean,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'AIError';\n }\n}\n\n/**\n * Classify an error and determine if it's retryable\n */\nfunction classifyError(error: unknown, config: AIClientConfig): { code: AIErrorCode; retryable: boolean; message: string } {\n if (error instanceof Anthropic.APIConnectionError) {\n return {\n code: 'CONNECTION_ERROR',\n retryable: true,\n message: `Connection error: ${error.message}`,\n };\n }\n\n if (error instanceof Anthropic.RateLimitError) {\n return {\n code: 'RATE_LIMITED',\n retryable: true,\n message: 'Rate limited by Anthropic API. Will retry with backoff.',\n };\n }\n\n if (error instanceof Anthropic.AuthenticationError) {\n return {\n code: 'INVALID_API_KEY',\n retryable: false,\n message: 'Invalid API key. Check ANTHROPIC_API_KEY environment variable.',\n };\n }\n\n if (error instanceof Anthropic.APIError) {\n // Check for overloaded error\n if (error.status === 529 || error.message.includes('overloaded')) {\n return {\n code: 'MODEL_OVERLOADED',\n retryable: true,\n message: 'Model is overloaded. Will retry with backoff.',\n };\n }\n\n // Check for timeout\n if (error.message.includes('timeout') || error.message.includes('timed out')) {\n return {\n code: 'TIMEOUT',\n retryable: true,\n message: `Request timed out after ${config.timeout}ms`,\n };\n }\n\n return {\n code: 'UNKNOWN',\n retryable: false,\n message: `API error: ${error.message}`,\n };\n }\n\n // Generic error handling\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('ENOTFOUND')) {\n return {\n code: 'CONNECTION_ERROR',\n retryable: true,\n message: `Network error: ${errorMessage}`,\n };\n }\n\n if (errorMessage.includes('timeout')) {\n return {\n code: 'TIMEOUT',\n retryable: true,\n message: `Request timed out: ${errorMessage}`,\n };\n }\n\n return {\n code: 'UNKNOWN',\n retryable: false,\n message: errorMessage,\n };\n}\n\n/**\n * Sleep for a specified duration\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Calculate exponential backoff delay\n */\nfunction getBackoffDelay(attempt: number, config: AIClientConfig): number {\n const delay = config.retryBaseDelay * Math.pow(2, attempt);\n // Add jitter (±20%)\n const jitter = delay * 0.2 * (Math.random() * 2 - 1);\n return Math.min(delay + jitter, config.retryMaxDelay);\n}\n\n/**\n * Parse JSON from AI response with robust extraction\n */\nfunction parseJsonFromResponse(text: string): string {\n let jsonText = text.trim();\n\n // Handle markdown code blocks (even with text before them)\n const codeBlockPatterns = [/```json\\s*([\\s\\S]*?)```/, /```\\s*([\\s\\S]*?)```/, /`([\\{\\[][\\s\\S]*?[\\}\\]])`/];\n\n for (const pattern of codeBlockPatterns) {\n const match = jsonText.match(pattern);\n if (match && match[1] && (match[1].includes('{') || match[1].includes('['))) {\n jsonText = match[1].trim();\n break;\n }\n }\n\n // Find the first { or [ and extract from there\n if (!jsonText.startsWith('{') && !jsonText.startsWith('[')) {\n const objectStart = jsonText.indexOf('{');\n const arrayStart = jsonText.indexOf('[');\n\n let startIdx = -1;\n if (objectStart >= 0 && arrayStart >= 0) {\n startIdx = Math.min(objectStart, arrayStart);\n } else if (objectStart >= 0) {\n startIdx = objectStart;\n } else if (arrayStart >= 0) {\n startIdx = arrayStart;\n }\n\n if (startIdx >= 0) {\n jsonText = jsonText.substring(startIdx);\n }\n }\n\n // Remove trailing text after JSON (find matching bracket)\n if (jsonText.startsWith('{') || jsonText.startsWith('[')) {\n const isObject = jsonText.startsWith('{');\n const openBracket = isObject ? '{' : '[';\n const closeBracket = isObject ? '}' : ']';\n let depth = 0;\n let inString = false;\n let escapeNext = false;\n let lastValidEnd = -1;\n\n for (let i = 0; i < jsonText.length; i++) {\n const char = jsonText[i];\n\n if (escapeNext) {\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\' && inString) {\n escapeNext = true;\n continue;\n }\n\n if (char === '\"') {\n inString = !inString;\n continue;\n }\n\n if (!inString) {\n if (char === openBracket) {\n depth++;\n } else if (char === closeBracket) {\n depth--;\n if (depth === 0) {\n lastValidEnd = i;\n jsonText = jsonText.substring(0, i + 1);\n break;\n }\n }\n }\n }\n\n // If we never found a valid end, the JSON is incomplete (likely truncated)\n if (lastValidEnd === -1 && depth > 0) {\n throw new AIError(\n `AI response was truncated (incomplete JSON with depth ${depth}). Try increasing maxTokens or reducing input size.`,\n 'TRUNCATED_RESPONSE',\n false\n );\n }\n }\n\n return jsonText;\n}\n\n// ============================================================================\n// AnthropicAIClient Class (Dependency Injection)\n// ============================================================================\n\n/**\n * Anthropic-based AI Client implementation.\n *\n * Supports dependency injection for testing and can be instantiated\n * with custom configuration. Use this class directly when you need\n * control over the client instance.\n *\n * @example\n * // Create a custom client\n * const client = new AnthropicAIClient({ config: { timeout: 60000 } });\n * const result = await client.createCompletion({ ... });\n *\n * @example\n * // Inject a mock client for testing\n * setDefaultAIClient(mockClient);\n */\nexport class AnthropicAIClient implements IAIClient {\n private client: Anthropic;\n private config: AIClientConfig;\n\n constructor(options: { apiKey?: string; config?: Partial<AIClientConfig> } = {}) {\n const apiKey = options.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new Error('ANTHROPIC_API_KEY environment variable is required');\n }\n\n this.config = { ...DEFAULT_AI_CONFIG, ...options.config };\n this.client = new Anthropic({\n apiKey,\n timeout: this.config.timeout,\n maxRetries: 0, // We handle retries ourselves for better control\n });\n }\n\n /**\n * Create a completion with retry logic\n */\n async createCompletion(options: CompletionOptions): Promise<CompletionResult> {\n const model = MODEL_TIERS[options.model || 'balanced'];\n const maxRetries = options.maxRetries ?? this.config.maxRetries;\n\n let lastError: AIError | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n // Log attempt for debugging\n if (attempt > 0) {\n console.error(`[VasperaPM AI] Retry attempt ${attempt}/${maxRetries}`);\n }\n\n const response = await this.client.messages.create({\n model,\n max_tokens: options.maxTokens || 4096,\n temperature: options.temperature ?? 0.7,\n system: options.systemPrompt,\n messages: [\n {\n role: 'user',\n content: options.userMessage,\n },\n ],\n });\n\n // Extract text from response\n const textContent = response.content.find((c) => c.type === 'text');\n const text = textContent?.type === 'text' ? textContent.text : '';\n\n return {\n text,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n } catch (error) {\n const classified = classifyError(error, this.config);\n\n lastError = new AIError(\n classified.message,\n classified.code,\n classified.retryable,\n error instanceof Error ? error : undefined\n );\n\n // Don't retry non-retryable errors\n if (!classified.retryable) {\n throw lastError;\n }\n\n // Don't retry if we've exhausted attempts\n if (attempt >= maxRetries) {\n console.error(`[VasperaPM AI] All ${maxRetries} retry attempts exhausted`);\n throw lastError;\n }\n\n // Calculate backoff and wait\n const delay = getBackoffDelay(attempt, this.config);\n console.error(`[VasperaPM AI] ${classified.code}: ${classified.message}. Retrying in ${Math.round(delay)}ms...`);\n await sleep(delay);\n }\n }\n\n // Should never reach here, but TypeScript needs it\n throw lastError || new AIError('Unknown error', 'UNKNOWN', false);\n }\n\n /**\n * Create a structured JSON completion\n */\n async createJsonCompletion<T>(options: JsonCompletionOptions): Promise<JsonCompletionResult<T>> {\n const result = await this.createCompletion({\n ...options,\n systemPrompt: `${options.systemPrompt}\\n\\nCRITICAL: Your response must be ONLY valid JSON. No explanatory text before or after. No markdown code blocks. Start directly with { or [ and end with } or ].`,\n temperature: 0.3, // Lower temperature for structured output\n });\n\n const jsonText = parseJsonFromResponse(result.text);\n\n try {\n const data = JSON.parse(jsonText) as T;\n\n // Validate expected keys if provided\n if (options.expectedKeys && typeof data === 'object' && data !== null) {\n const missingKeys = options.expectedKeys.filter((key) => !(key in data));\n if (missingKeys.length > 0) {\n console.error(`[VasperaPM AI] Warning: Response missing expected keys: ${missingKeys.join(', ')}`);\n }\n }\n\n return {\n data,\n inputTokens: result.inputTokens,\n outputTokens: result.outputTokens,\n };\n } catch (error) {\n // Log more details for debugging\n const debugInfo = {\n originalLength: result.text.length,\n extractedLength: jsonText.length,\n startsWithBracket: jsonText[0],\n first100: jsonText.substring(0, 100),\n last100: jsonText.substring(Math.max(0, jsonText.length - 100)),\n };\n\n throw new AIError(\n `Failed to parse AI response as JSON: ${result.text.substring(0, 200)}\\n\\nDebug: ${JSON.stringify(debugInfo, null, 2)}`,\n 'INVALID_JSON',\n false,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Process multiple chunks with individual AI calls\n */\n async createChunkedCompletion<T>(options: ChunkedCompletionOptions): Promise<ChunkedCompletionResult<T>> {\n const {\n systemPrompt,\n chunks,\n chunkPromptTemplate,\n model = 'balanced',\n maxTokens = 4096,\n parallel = false,\n maxParallel = 3,\n onProgress,\n } = options;\n\n const results: Array<{ id: string; data: T; inputTokens: number; outputTokens: number }> = [];\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n\n const processChunk = async (chunk: { id: string; content: string }, index: number) => {\n const userMessage = chunkPromptTemplate\n .replace(/\\{\\{content\\}\\}/g, chunk.content)\n .replace(/\\{\\{id\\}\\}/g, chunk.id);\n\n const result = await this.createJsonCompletion<T>({\n systemPrompt,\n userMessage,\n model,\n maxTokens,\n });\n\n onProgress?.(index + 1, chunks.length, chunk.id);\n\n return {\n id: chunk.id,\n data: result.data,\n inputTokens: result.inputTokens,\n outputTokens: result.outputTokens,\n };\n };\n\n if (parallel) {\n // Process in batches for parallel execution\n for (let i = 0; i < chunks.length; i += maxParallel) {\n const batch = chunks.slice(i, i + maxParallel);\n const batchResults = await Promise.all(batch.map((chunk, batchIndex) => processChunk(chunk, i + batchIndex)));\n results.push(...batchResults);\n }\n } else {\n // Sequential processing (safer for rate limits)\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n if (chunk) {\n const result = await processChunk(chunk, i);\n results.push(result);\n }\n }\n }\n\n // Calculate totals\n for (const result of results) {\n totalInputTokens += result.inputTokens;\n totalOutputTokens += result.outputTokens;\n }\n\n return {\n results,\n totalInputTokens,\n totalOutputTokens,\n };\n }\n\n /**\n * Get the underlying Anthropic client (for advanced usage)\n */\n getRawClient(): Anthropic {\n return this.client;\n }\n\n /**\n * Get the current configuration\n */\n getConfig(): AIClientConfig {\n return { ...this.config };\n }\n}\n\n// ============================================================================\n// Default Instance & Backward-Compatible API\n// ============================================================================\n\n// Default singleton instance (lazy initialization)\nlet defaultClient: IAIClient | null = null;\nlet pendingConfig: Partial<AIClientConfig> = {};\n\n/**\n * Get the default AI client instance.\n *\n * Returns the singleton instance, creating it if necessary.\n * Use setDefaultAIClient() to inject a mock for testing.\n */\nexport function getDefaultAIClient(): IAIClient {\n if (!defaultClient) {\n defaultClient = new AnthropicAIClient({ config: pendingConfig });\n }\n return defaultClient;\n}\n\n/**\n * Set a custom AI client as the default.\n *\n * Use this for dependency injection in tests:\n * @example\n * // In test setup\n * const mockClient = { createCompletion: vi.fn(), ... };\n * setDefaultAIClient(mockClient);\n *\n * // In test teardown\n * setDefaultAIClient(null);\n */\nexport function setDefaultAIClient(client: IAIClient | null): void {\n defaultClient = client;\n}\n\n/**\n * Configure the default AI client settings.\n *\n * Must be called before getDefaultAIClient() to take effect,\n * or call with resetClient=true to reset the existing client.\n */\nexport function configureAIClient(config: Partial<AIClientConfig>): void {\n pendingConfig = { ...pendingConfig, ...config };\n // Reset client to apply new config on next access\n defaultClient = null;\n}\n\n/**\n * Get the Anthropic client instance.\n *\n * @deprecated Use getDefaultAIClient() for DI support, or create AnthropicAIClient directly\n */\nexport function getAnthropicClient(): Anthropic {\n const client = getDefaultAIClient();\n if (client instanceof AnthropicAIClient) {\n return client.getRawClient();\n }\n throw new Error('Default client does not expose raw Anthropic client. Use AnthropicAIClient directly.');\n}\n\n// ============================================================================\n// Backward-Compatible Constants\n// ============================================================================\n\n/**\n * Default model for VasperaPM tools\n * @deprecated Use DEFAULT_MODELS.default from @vaspera/shared\n */\nexport const DEFAULT_MODEL = DEFAULT_MODELS.default;\n\n/**\n * Model options by capability tier\n * @deprecated Use MODEL_TIERS from @vaspera/shared\n */\nexport const MODELS = MODEL_TIERS;\n\n// ============================================================================\n// Backward-Compatible Functions (use default client)\n// ============================================================================\n\n/**\n * Create a completion with Claude.\n *\n * This is a convenience function that uses the default AI client.\n * For dependency injection, use getDefaultAIClient() or create an AnthropicAIClient.\n */\nexport async function createCompletion(options: CompletionOptions): Promise<CompletionResult> {\n return getDefaultAIClient().createCompletion(options);\n}\n\n/**\n * Create a structured JSON completion with Claude.\n *\n * This is a convenience function that uses the default AI client.\n * For dependency injection, use getDefaultAIClient() or create an AnthropicAIClient.\n */\nexport async function createJsonCompletion<T>(options: JsonCompletionOptions): Promise<JsonCompletionResult<T>> {\n return getDefaultAIClient().createJsonCompletion<T>(options);\n}\n\n/**\n * Process multiple chunks with individual AI calls.\n *\n * This is a convenience function that uses the default AI client.\n * For dependency injection, use getDefaultAIClient() or create an AnthropicAIClient.\n */\nexport async function createChunkedCompletion<T>(options: ChunkedCompletionOptions): Promise<ChunkedCompletionResult<T>> {\n return getDefaultAIClient().createChunkedCompletion<T>(options);\n}\n","import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync, readFileSync } from 'fs';\nimport { join, basename, dirname } from 'path';\nimport type { OutputCategory, VasperaPMConfig } from '@vaspera/shared';\n\n/**\n * VasperaPM Output Folder Manager\n *\n * Handles detection and creation of output folders for generated documentation.\n *\n * Logic:\n * - If project has /docs/ folder → create /docs/vasperaPM/\n * - If project has /spec/ folder → create /spec/vasperaPM/\n * - Otherwise → create /vasperaPM_Docs/ at project root\n */\n\nconst VASPERA_FOLDER = 'vasperaPM';\nconst VASPERA_STANDALONE = 'vasperaPM_Docs';\nconst CONFIG_FILE = '_metadata/config.json';\nconst HISTORY_FILE = '_metadata/history.json';\n\n// Standard folder structure\nconst FOLDER_STRUCTURE: OutputCategory[] = [\n 'requirements',\n 'prd',\n 'backlog',\n 'architecture',\n 'test-specs',\n 'code-analysis',\n 'api',\n 'handoff',\n 'changelog',\n];\n\nconst SUBFOLDER_STRUCTURE: Record<string, string[]> = {\n backlog: ['epics', 'stories'],\n architecture: ['diagrams', 'decisions'],\n 'test-specs': ['unit_tests', 'e2e_tests'],\n};\n\n/**\n * Detect the correct output folder path for a project\n */\nexport function detectOutputPath(projectRoot: string): string {\n // Check for /docs/ folder\n const docsPath = join(projectRoot, 'docs');\n if (existsSync(docsPath) && statSync(docsPath).isDirectory()) {\n return join(docsPath, VASPERA_FOLDER);\n }\n\n // Check for /spec/ folder\n const specPath = join(projectRoot, 'spec');\n if (existsSync(specPath) && statSync(specPath).isDirectory()) {\n return join(specPath, VASPERA_FOLDER);\n }\n\n // Default to standalone folder at root\n return join(projectRoot, VASPERA_STANDALONE);\n}\n\n/**\n * Initialize the VasperaPM output folder structure\n */\nexport function initializeOutputFolder(projectRoot: string): string {\n const outputPath = detectOutputPath(projectRoot);\n\n // Create main folder\n if (!existsSync(outputPath)) {\n mkdirSync(outputPath, { recursive: true });\n }\n\n // Create category folders\n for (const category of FOLDER_STRUCTURE) {\n const categoryPath = join(outputPath, category);\n if (!existsSync(categoryPath)) {\n mkdirSync(categoryPath, { recursive: true });\n }\n\n // Create subfolders if defined\n const subfolders = SUBFOLDER_STRUCTURE[category];\n if (subfolders) {\n for (const subfolder of subfolders) {\n const subfolderPath = join(categoryPath, subfolder);\n if (!existsSync(subfolderPath)) {\n mkdirSync(subfolderPath, { recursive: true });\n }\n }\n }\n }\n\n // Create _metadata folder\n const metadataPath = join(outputPath, '_metadata');\n if (!existsSync(metadataPath)) {\n mkdirSync(metadataPath, { recursive: true });\n }\n\n // Initialize config if not exists\n const configPath = join(outputPath, CONFIG_FILE);\n if (!existsSync(configPath)) {\n const config: VasperaPMConfig = {\n outputPath,\n fileVersioning: 'semantic',\n };\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n }\n\n // Initialize history if not exists\n const historyPath = join(outputPath, HISTORY_FILE);\n if (!existsSync(historyPath)) {\n writeFileSync(historyPath, JSON.stringify({ invocations: [] }, null, 2));\n }\n\n return outputPath;\n}\n\n/**\n * Get the config for an output folder\n */\nexport function getConfig(outputPath: string): VasperaPMConfig | null {\n const configPath = join(outputPath, CONFIG_FILE);\n if (!existsSync(configPath)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(configPath, 'utf-8'));\n } catch {\n return null;\n }\n}\n\n/**\n * Update the config for an output folder\n */\nexport function updateConfig(outputPath: string, updates: Partial<VasperaPMConfig>): void {\n const configPath = join(outputPath, CONFIG_FILE);\n const existing = getConfig(outputPath) || { outputPath, fileVersioning: 'semantic' as const };\n const updated = { ...existing, ...updates };\n writeFileSync(configPath, JSON.stringify(updated, null, 2));\n}\n\n/**\n * Get the next version number for a file in a category\n */\nexport function getNextVersion(outputPath: string, category: OutputCategory, baseName: string): string {\n const categoryPath = join(outputPath, category);\n if (!existsSync(categoryPath)) {\n return '1.0';\n }\n\n const files = readdirSync(categoryPath);\n const versionPattern = new RegExp(`^${baseName}_v(\\\\d+)\\\\.(\\\\d+)\\\\.(md|json)$`);\n\n let maxMajor = 0;\n let maxMinor = 0;\n\n for (const file of files) {\n const match = file.match(versionPattern);\n if (match) {\n const major = parseInt(match[1], 10);\n const minor = parseInt(match[2], 10);\n if (major > maxMajor || (major === maxMajor && minor > maxMinor)) {\n maxMajor = major;\n maxMinor = minor;\n }\n }\n }\n\n if (maxMajor === 0 && maxMinor === 0) {\n return '1.0';\n }\n\n // Increment minor version\n return `${maxMajor}.${maxMinor + 1}`;\n}\n\n/**\n * Generate a versioned filename\n */\nexport function getVersionedFilename(\n outputPath: string,\n category: OutputCategory,\n baseName: string,\n extension: 'md' | 'json' = 'md'\n): string {\n const version = getNextVersion(outputPath, category, baseName);\n return `${baseName}_v${version}.${extension}`;\n}\n\n/**\n * Get full path for a new output file\n */\nexport function getOutputFilePath(\n outputPath: string,\n category: OutputCategory,\n baseName: string,\n extension: 'md' | 'json' = 'md',\n subfolder?: string\n): string {\n const filename = getVersionedFilename(outputPath, category, baseName, extension);\n\n if (subfolder && SUBFOLDER_STRUCTURE[category]?.includes(subfolder)) {\n return join(outputPath, category, subfolder, filename);\n }\n\n return join(outputPath, category, filename);\n}\n\n/**\n * Log a tool invocation to history\n */\nexport function logInvocation(\n outputPath: string,\n toolName: string,\n inputs: string[],\n outputFile: string,\n tokensUsed: number,\n status: 'complete' | 'partial' | 'error'\n): void {\n const historyPath = join(outputPath, HISTORY_FILE);\n let history: { invocations: unknown[] } = { invocations: [] };\n\n if (existsSync(historyPath)) {\n try {\n history = JSON.parse(readFileSync(historyPath, 'utf-8'));\n } catch {\n // Reset if corrupted\n }\n }\n\n history.invocations.push({\n timestamp: new Date().toISOString(),\n tool: toolName,\n inputs,\n output: outputFile,\n tokensUsed,\n status,\n });\n\n writeFileSync(historyPath, JSON.stringify(history, null, 2));\n}\n\n/**\n * Check if a VasperaPM output folder exists for a project\n */\nexport function hasOutputFolder(projectRoot: string): boolean {\n const outputPath = detectOutputPath(projectRoot);\n return existsSync(outputPath);\n}\n\n/**\n * Ensure output folder structure exists (alias for initializeOutputFolder)\n */\nexport function ensureOutputStructure(outputPath: string): void {\n // Get project root from output path\n const projectRoot = outputPath.includes(VASPERA_FOLDER)\n ? dirname(dirname(outputPath))\n : dirname(outputPath);\n initializeOutputFolder(projectRoot);\n}\n\n/**\n * Get the path to a category folder\n */\nexport function getCategoryPath(outputPath: string, category: OutputCategory): string {\n const categoryPath = join(outputPath, category);\n if (!existsSync(categoryPath)) {\n mkdirSync(categoryPath, { recursive: true });\n }\n return categoryPath;\n}\n\n/**\n * Log a tool invocation (simplified alias for logInvocation)\n */\nexport function logToolInvocation(\n outputPath: string,\n toolName: string,\n outputFile: string,\n tokensUsed: number\n): void {\n logInvocation(outputPath, toolName, [], outputFile, tokensUsed, 'complete');\n}\n\n/**\n * Get all generated files in a category\n */\nexport function listCategoryFiles(outputPath: string, category: OutputCategory): string[] {\n const categoryPath = join(outputPath, category);\n if (!existsSync(categoryPath)) {\n return [];\n }\n\n const files: string[] = [];\n\n const entries = readdirSync(categoryPath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile()) {\n files.push(entry.name);\n } else if (entry.isDirectory()) {\n // Check subfolders\n const subPath = join(categoryPath, entry.name);\n const subEntries = readdirSync(subPath, { withFileTypes: true });\n for (const subEntry of subEntries) {\n if (subEntry.isFile()) {\n files.push(join(entry.name, subEntry.name));\n }\n }\n }\n }\n\n return files;\n}\n","import type { VasperaPMFileMetadata } from '@vaspera/shared';\n\nconst VERSION = '0.2.1';\n\n/**\n * Generate YAML frontmatter metadata header for generated files\n */\nexport function generateMetadataHeader(\n toolName: string,\n inputs: string[],\n tokensUsed: number,\n fileVersion: string,\n status: 'complete' | 'partial' | 'error' = 'complete'\n): string {\n const metadata: VasperaPMFileMetadata = {\n tool: toolName,\n version: VERSION,\n generated: new Date().toISOString(),\n inputs: inputs.length > 0 ? inputs : undefined,\n tokensUsed,\n status,\n fileVersion,\n };\n\n const lines = ['---', 'vasperaPM:'];\n\n lines.push(` tool: ${metadata.tool}`);\n lines.push(` version: ${metadata.version}`);\n lines.push(` generated: ${metadata.generated}`);\n\n if (metadata.inputs && metadata.inputs.length > 0) {\n lines.push(' inputs:');\n for (const input of metadata.inputs) {\n lines.push(` - ${input}`);\n }\n }\n\n if (metadata.tokensUsed !== undefined) {\n lines.push(` tokens_used: ${metadata.tokensUsed}`);\n }\n\n lines.push(` status: ${metadata.status}`);\n lines.push(` file_version: \"${metadata.fileVersion}\"`);\n lines.push('---', '');\n\n return lines.join('\\n');\n}\n\n/**\n * Wrap content with metadata header\n */\nexport function wrapWithMetadata(\n content: string,\n toolName: string,\n inputs: string[],\n tokensUsed: number,\n fileVersion: string,\n status: 'complete' | 'partial' | 'error' = 'complete'\n): string {\n const header = generateMetadataHeader(toolName, inputs, tokensUsed, fileVersion, status);\n return header + content;\n}\n\n/**\n * Parse metadata from a file's YAML frontmatter\n */\nexport function parseMetadata(content: string): VasperaPMFileMetadata | null {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) {\n return null;\n }\n\n try {\n const yaml = frontmatterMatch[1];\n const lines = yaml.split('\\n');\n\n const metadata: Partial<VasperaPMFileMetadata> = {};\n let currentKey = '';\n let inInputs = false;\n const inputs: string[] = [];\n\n for (const line of lines) {\n // Skip vasperaPM: header\n if (line.trim() === 'vasperaPM:') continue;\n\n // Check for inputs array items\n if (inInputs && line.match(/^\\s+-\\s+/)) {\n inputs.push(line.replace(/^\\s+-\\s+/, '').trim());\n continue;\n }\n\n // Key-value parsing\n const kvMatch = line.match(/^\\s+(\\w+):\\s*(.*)$/);\n if (kvMatch) {\n const [, key, value] = kvMatch;\n inInputs = key === 'inputs' && !value;\n\n switch (key) {\n case 'tool':\n metadata.tool = value;\n break;\n case 'version':\n metadata.version = value;\n break;\n case 'generated':\n metadata.generated = value;\n break;\n case 'tokens_used':\n metadata.tokensUsed = parseInt(value, 10);\n break;\n case 'status':\n metadata.status = value as 'complete' | 'partial' | 'error';\n break;\n case 'file_version':\n metadata.fileVersion = value.replace(/\"/g, '');\n break;\n }\n }\n }\n\n if (inputs.length > 0) {\n metadata.inputs = inputs;\n }\n\n if (metadata.tool && metadata.version && metadata.generated && metadata.status && metadata.fileVersion) {\n return metadata as VasperaPMFileMetadata;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract content without metadata header\n */\nexport function stripMetadata(content: string): string {\n return content.replace(/^---\\n[\\s\\S]*?\\n---\\n/, '');\n}\n\n/**\n * Get version from filename\n */\nexport function extractVersionFromFilename(filename: string): string | null {\n const match = filename.match(/_v(\\d+\\.\\d+)\\.(md|json)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Generate JSON metadata for JSON export files\n */\nexport function generateJsonMetadata(\n toolName: string,\n inputs: string[],\n tokensUsed: number,\n fileVersion: string,\n status: 'complete' | 'partial' | 'error' = 'complete'\n): Record<string, unknown> {\n return {\n _vasperaPM: {\n tool: toolName,\n version: VERSION,\n generated: new Date().toISOString(),\n inputs: inputs.length > 0 ? inputs : undefined,\n tokensUsed,\n status,\n fileVersion,\n },\n };\n}\n","/**\n * Cache Manager Module\n *\n * Manages JSON cache for document diffing.\n * Stores structured data alongside markdown files for efficient comparison.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, statSync, unlinkSync } from 'fs';\nimport { join, dirname, basename } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CachedDocument<T = unknown> {\n version: string;\n timestamp: string;\n documentType: string;\n toolName: string;\n inputHash: string;\n data: T;\n}\n\nexport interface CacheStats {\n totalFiles: number;\n totalSizeBytes: number;\n byCategory: Record<string, number>;\n oldestFile?: string;\n newestFile?: string;\n}\n\n// ============================================================================\n// Path Helpers\n// ============================================================================\n\n/**\n * Get the cache directory path\n */\nexport function getCacheDir(projectRoot: string): string {\n return join(projectRoot, 'docs', 'vasperaPM', '.cache');\n}\n\n/**\n * Get the cache file path for a specific document\n */\nexport function getCacheFilePath(projectRoot: string, category: string, filename: string, version: string): string {\n const cacheDir = join(getCacheDir(projectRoot), category);\n return join(cacheDir, `${filename}_v${version}.json`);\n}\n\n/**\n * Ensure cache directory exists\n */\nfunction ensureCacheDir(projectRoot: string, category: string): void {\n const cacheDir = join(getCacheDir(projectRoot), category);\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n}\n\n// ============================================================================\n// Main Functions\n// ============================================================================\n\n/**\n * Save document data to cache\n */\nexport function saveToCache<T>(\n projectRoot: string,\n options: {\n category: string;\n filename: string;\n version: string;\n documentType: string;\n toolName: string;\n inputHash: string;\n data: T;\n }\n): string {\n ensureCacheDir(projectRoot, options.category);\n\n const cachedDoc: CachedDocument<T> = {\n version: options.version,\n timestamp: new Date().toISOString(),\n documentType: options.documentType,\n toolName: options.toolName,\n inputHash: options.inputHash,\n data: options.data,\n };\n\n const cachePath = getCacheFilePath(projectRoot, options.category, options.filename, options.version);\n writeFileSync(cachePath, JSON.stringify(cachedDoc, null, 2), 'utf-8');\n\n return cachePath;\n}\n\n/**\n * Load document data from cache\n */\nexport function loadFromCache<T>(\n projectRoot: string,\n category: string,\n filename: string,\n version: string\n): CachedDocument<T> | null {\n const cachePath = getCacheFilePath(projectRoot, category, filename, version);\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(cachePath, 'utf-8');\n return JSON.parse(content) as CachedDocument<T>;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the latest cached version for a document\n */\nexport function getLatestCachedVersion(\n projectRoot: string,\n category: string,\n filename: string\n): CachedDocument | null {\n const cacheDir = join(getCacheDir(projectRoot), category);\n\n if (!existsSync(cacheDir)) {\n return null;\n }\n\n const files = readdirSync(cacheDir)\n .filter((f) => f.startsWith(filename) && f.endsWith('.json'))\n .sort()\n .reverse();\n\n if (files.length === 0) {\n return null;\n }\n\n try {\n const content = readFileSync(join(cacheDir, files[0]), 'utf-8');\n return JSON.parse(content) as CachedDocument;\n } catch {\n return null;\n }\n}\n\n/**\n * Get all cached versions for a document\n */\nexport function getAllCachedVersions(\n projectRoot: string,\n category: string,\n filename: string\n): string[] {\n const cacheDir = join(getCacheDir(projectRoot), category);\n\n if (!existsSync(cacheDir)) {\n return [];\n }\n\n return readdirSync(cacheDir)\n .filter((f) => f.startsWith(filename) && f.endsWith('.json'))\n .map((f) => {\n // Extract version from filename like \"complete_backlog_v1.0.json\"\n const match = f.match(/_v(\\d+\\.\\d+)\\.json$/);\n return match ? match[1] : '';\n })\n .filter(Boolean)\n .sort();\n}\n\n/**\n * Get the previous version number\n */\nexport function getPreviousVersion(\n projectRoot: string,\n category: string,\n filename: string,\n currentVersion: string\n): string | null {\n const versions = getAllCachedVersions(projectRoot, category, filename);\n const currentIndex = versions.indexOf(currentVersion);\n\n if (currentIndex <= 0) {\n return null;\n }\n\n return versions[currentIndex - 1];\n}\n\n/**\n * Get cache statistics\n */\nexport function getCacheStats(projectRoot: string): CacheStats {\n const cacheDir = getCacheDir(projectRoot);\n\n if (!existsSync(cacheDir)) {\n return {\n totalFiles: 0,\n totalSizeBytes: 0,\n byCategory: {},\n };\n }\n\n let totalFiles = 0;\n let totalSizeBytes = 0;\n const byCategory: Record<string, number> = {};\n let oldestTime = Infinity;\n let newestTime = 0;\n let oldestFile: string | undefined;\n let newestFile: string | undefined;\n\n const categories = readdirSync(cacheDir).filter((f) => {\n const fullPath = join(cacheDir, f);\n return existsSync(fullPath) && statSync(fullPath).isDirectory();\n });\n\n for (const category of categories) {\n const categoryDir = join(cacheDir, category);\n const files = readdirSync(categoryDir).filter((f) => f.endsWith('.json'));\n\n byCategory[category] = files.length;\n totalFiles += files.length;\n\n for (const file of files) {\n const filePath = join(categoryDir, file);\n const stats = statSync(filePath);\n totalSizeBytes += stats.size;\n\n if (stats.mtimeMs < oldestTime) {\n oldestTime = stats.mtimeMs;\n oldestFile = join(category, file);\n }\n\n if (stats.mtimeMs > newestTime) {\n newestTime = stats.mtimeMs;\n newestFile = join(category, file);\n }\n }\n }\n\n return {\n totalFiles,\n totalSizeBytes,\n byCategory,\n oldestFile,\n newestFile,\n };\n}\n\n/**\n * Prune old cache files to stay under size limit\n */\nexport function pruneCache(projectRoot: string, maxSizeBytes: number = 100 * 1024 * 1024): number {\n const cacheDir = getCacheDir(projectRoot);\n\n if (!existsSync(cacheDir)) {\n return 0;\n }\n\n // Get all cache files with their timestamps\n const allFiles: { path: string; mtime: number; size: number }[] = [];\n\n const categories = readdirSync(cacheDir).filter((f) => {\n const fullPath = join(cacheDir, f);\n return existsSync(fullPath) && statSync(fullPath).isDirectory();\n });\n\n for (const category of categories) {\n const categoryDir = join(cacheDir, category);\n const files = readdirSync(categoryDir).filter((f) => f.endsWith('.json'));\n\n for (const file of files) {\n const filePath = join(categoryDir, file);\n const stats = statSync(filePath);\n allFiles.push({ path: filePath, mtime: stats.mtimeMs, size: stats.size });\n }\n }\n\n // Sort by age (oldest first)\n allFiles.sort((a, b) => a.mtime - b.mtime);\n\n // Calculate total size\n let totalSize = allFiles.reduce((sum, f) => sum + f.size, 0);\n let deletedCount = 0;\n\n // Delete oldest files until under limit\n while (totalSize > maxSizeBytes && allFiles.length > 0) {\n const oldest = allFiles.shift()!;\n try {\n unlinkSync(oldest.path);\n totalSize -= oldest.size;\n deletedCount++;\n } catch {\n // Ignore deletion errors\n }\n }\n\n return deletedCount;\n}\n\n/**\n * Clear all cache for a specific category\n */\nexport function clearCategoryCache(projectRoot: string, category: string): number {\n const categoryDir = join(getCacheDir(projectRoot), category);\n\n if (!existsSync(categoryDir)) {\n return 0;\n }\n\n const files = readdirSync(categoryDir).filter((f) => f.endsWith('.json'));\n let deletedCount = 0;\n\n for (const file of files) {\n try {\n unlinkSync(join(categoryDir, file));\n deletedCount++;\n } catch {\n // Ignore deletion errors\n }\n }\n\n return deletedCount;\n}\n","/**\n * Audit Log Module\n *\n * Provides immutable audit trail for all VasperaPM document changes.\n * Events are appended to a JSONL file for compliance and debugging.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { randomUUID } from 'crypto';\nimport { createHash } from 'crypto';\nimport { execSync } from 'child_process';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AuditEvent {\n id: string;\n timestamp: string;\n eventType: 'create' | 'update' | 'delete' | 'sync';\n documentType: string;\n documentPath: string;\n version: string;\n previousVersion?: string;\n toolName: string;\n tokensUsed: number;\n inputHash: string;\n outputHash: string;\n user?: string;\n gitCommit?: string;\n gitBranch?: string;\n changes?: ChangeSummary;\n}\n\nexport interface ChangeSummary {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n addedItems: ChangeItem[];\n removedItems: ChangeItem[];\n modifiedItems: ModifiedItem[];\n totalPointsBefore?: number;\n totalPointsAfter?: number;\n pointsDelta?: number;\n hasRegressions: boolean;\n hasScopeCreep: boolean;\n hasEstimateInflation: boolean;\n}\n\nexport interface ChangeItem {\n id: string;\n title: string;\n type: 'epic' | 'issue' | 'task' | 'requirement' | 'feature';\n category?: string;\n priority?: string;\n estimate?: number;\n}\n\nexport interface ModifiedItem extends ChangeItem {\n changes: FieldChange[];\n}\n\nexport interface FieldChange {\n field: string;\n oldValue: string | number;\n newValue: string | number;\n significance: 'low' | 'medium' | 'high' | 'critical';\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Compute SHA256 hash of content\n */\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').substring(0, 16);\n}\n\n/**\n * Get current git commit hash\n */\nfunction getGitCommit(projectRoot: string): string | undefined {\n try {\n return execSync('git rev-parse HEAD', {\n cwd: projectRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim().substring(0, 8);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get current git branch\n */\nfunction getGitBranch(projectRoot: string): string | undefined {\n try {\n return execSync('git rev-parse --abbrev-ref HEAD', {\n cwd: projectRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get the audit log file path\n */\nexport function getAuditLogPath(projectRoot: string): string {\n return join(projectRoot, 'docs', 'vasperaPM', '.history', 'audit_log.jsonl');\n}\n\n/**\n * Ensure the history directory exists\n */\nfunction ensureHistoryDir(projectRoot: string): void {\n const historyDir = join(projectRoot, 'docs', 'vasperaPM', '.history');\n if (!existsSync(historyDir)) {\n mkdirSync(historyDir, { recursive: true });\n }\n}\n\n// ============================================================================\n// Main Functions\n// ============================================================================\n\n/**\n * Append an audit event to the log\n */\nexport function appendAuditEvent(projectRoot: string, event: Omit<AuditEvent, 'id' | 'timestamp' | 'gitCommit' | 'gitBranch'>): AuditEvent {\n ensureHistoryDir(projectRoot);\n\n const fullEvent: AuditEvent = {\n ...event,\n id: randomUUID(),\n timestamp: new Date().toISOString(),\n gitCommit: getGitCommit(projectRoot),\n gitBranch: getGitBranch(projectRoot),\n user: process.env.USER || process.env.USERNAME,\n };\n\n const logPath = getAuditLogPath(projectRoot);\n appendFileSync(logPath, JSON.stringify(fullEvent) + '\\n', 'utf-8');\n\n return fullEvent;\n}\n\n/**\n * Read all audit events\n */\nexport function readAuditEvents(projectRoot: string): AuditEvent[] {\n const logPath = getAuditLogPath(projectRoot);\n\n if (!existsSync(logPath)) {\n return [];\n }\n\n const content = readFileSync(logPath, 'utf-8');\n const lines = content.trim().split('\\n').filter(Boolean);\n\n return lines.map((line) => JSON.parse(line) as AuditEvent);\n}\n\n/**\n * Query audit events with filters\n */\nexport function queryAuditEvents(\n projectRoot: string,\n filters: {\n documentType?: string;\n documentPath?: string;\n startDate?: string;\n endDate?: string;\n eventTypes?: AuditEvent['eventType'][];\n limit?: number;\n }\n): AuditEvent[] {\n let events = readAuditEvents(projectRoot);\n\n // Apply filters\n if (filters.documentType) {\n events = events.filter((e) => e.documentType === filters.documentType);\n }\n\n if (filters.documentPath) {\n events = events.filter((e) => e.documentPath.includes(filters.documentPath!));\n }\n\n if (filters.startDate) {\n const start = new Date(filters.startDate);\n events = events.filter((e) => new Date(e.timestamp) >= start);\n }\n\n if (filters.endDate) {\n const end = new Date(filters.endDate);\n events = events.filter((e) => new Date(e.timestamp) <= end);\n }\n\n if (filters.eventTypes && filters.eventTypes.length > 0) {\n events = events.filter((e) => filters.eventTypes!.includes(e.eventType));\n }\n\n // Sort by timestamp descending (most recent first)\n events.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n // Apply limit\n if (filters.limit && filters.limit > 0) {\n events = events.slice(0, filters.limit);\n }\n\n return events;\n}\n\n/**\n * Get events for a specific document\n */\nexport function getDocumentHistory(projectRoot: string, documentPath: string): AuditEvent[] {\n return queryAuditEvents(projectRoot, { documentPath });\n}\n\n/**\n * Get the last event for a document type\n */\nexport function getLastEvent(projectRoot: string, documentType: string): AuditEvent | undefined {\n const events = queryAuditEvents(projectRoot, { documentType, limit: 1 });\n return events[0];\n}\n\n/**\n * Get summary statistics from audit log\n */\nexport function getAuditSummary(projectRoot: string): {\n totalEvents: number;\n byEventType: Record<string, number>;\n byDocumentType: Record<string, number>;\n totalTokensUsed: number;\n firstEvent?: string;\n lastEvent?: string;\n} {\n const events = readAuditEvents(projectRoot);\n\n const byEventType: Record<string, number> = {};\n const byDocumentType: Record<string, number> = {};\n let totalTokensUsed = 0;\n\n for (const event of events) {\n byEventType[event.eventType] = (byEventType[event.eventType] || 0) + 1;\n byDocumentType[event.documentType] = (byDocumentType[event.documentType] || 0) + 1;\n totalTokensUsed += event.tokensUsed || 0;\n }\n\n return {\n totalEvents: events.length,\n byEventType,\n byDocumentType,\n totalTokensUsed,\n firstEvent: events.length > 0 ? events[events.length - 1].timestamp : undefined,\n lastEvent: events.length > 0 ? events[0].timestamp : undefined,\n };\n}\n","/**\n * Diff Engine Module\n *\n * Provides intelligent diffing for VasperaPM documents.\n * Detects added, removed, and modified items with field-level tracking.\n */\n\nimport type { ChangeSummary, ChangeItem, ModifiedItem, FieldChange } from './audit-log.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BacklogIssue {\n id: string;\n title: string;\n description?: string;\n priority?: 'critical' | 'high' | 'medium' | 'low';\n estimate?: string | number;\n category?: string;\n acceptanceCriteria?: string[];\n tasks?: Array<{ id: string; title: string; estimate?: string }>;\n}\n\nexport interface BacklogEpic {\n id: string;\n title: string;\n description?: string;\n category?: string;\n issues: BacklogIssue[];\n}\n\nexport interface BacklogOutput {\n epics: BacklogEpic[];\n summary?: {\n totalEpics: number;\n totalIssues: number;\n totalTasks: number;\n byCategory?: Record<string, number>;\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Flatten all issues from a backlog into a single array\n */\nexport function flattenIssues(backlog: BacklogOutput): BacklogIssue[] {\n const issues: BacklogIssue[] = [];\n\n for (const epic of backlog.epics || []) {\n for (const issue of epic.issues || []) {\n issues.push({\n ...issue,\n category: issue.category || epic.category,\n });\n }\n }\n\n return issues;\n}\n\n/**\n * Convert an issue to a ChangeItem\n */\nfunction toChangeItem(issue: BacklogIssue): ChangeItem {\n return {\n id: issue.id,\n title: issue.title,\n type: 'issue',\n category: issue.category,\n priority: issue.priority,\n estimate: typeof issue.estimate === 'string' ? parseInt(issue.estimate, 10) : issue.estimate,\n };\n}\n\n/**\n * Sum all estimates in a backlog\n */\nexport function sumEstimates(backlog: BacklogOutput): number {\n let total = 0;\n\n for (const epic of backlog.epics || []) {\n for (const issue of epic.issues || []) {\n const estimate = typeof issue.estimate === 'string' ? parseInt(issue.estimate, 10) : issue.estimate;\n if (!isNaN(estimate as number)) {\n total += estimate as number;\n }\n }\n }\n\n return total;\n}\n\n/**\n * Count all tasks in a backlog\n */\nexport function countTasks(backlog: BacklogOutput): number {\n let total = 0;\n\n for (const epic of backlog.epics || []) {\n for (const issue of epic.issues || []) {\n total += issue.tasks?.length || 0;\n }\n }\n\n return total;\n}\n\n/**\n * Get field significance for change tracking\n */\nfunction getFieldSignificance(field: string): FieldChange['significance'] {\n const highSignificance = ['priority', 'estimate', 'category'];\n const mediumSignificance = ['title', 'tasks'];\n const criticalSignificance = ['id'];\n\n if (criticalSignificance.includes(field)) return 'critical';\n if (highSignificance.includes(field)) return 'high';\n if (mediumSignificance.includes(field)) return 'medium';\n return 'low';\n}\n\n// ============================================================================\n// Main Diffing Functions\n// ============================================================================\n\n/**\n * Diff two issues and return field-level changes\n */\nexport function diffIssue(oldIssue: BacklogIssue, newIssue: BacklogIssue): FieldChange[] {\n const changes: FieldChange[] = [];\n\n // Compare simple fields\n const simpleFields: (keyof BacklogIssue)[] = ['title', 'description', 'priority', 'estimate', 'category'];\n\n for (const field of simpleFields) {\n const oldValue = oldIssue[field];\n const newValue = newIssue[field];\n\n if (oldValue !== newValue) {\n changes.push({\n field,\n oldValue: oldValue as string | number,\n newValue: newValue as string | number,\n significance: getFieldSignificance(field),\n });\n }\n }\n\n // Compare acceptance criteria\n const oldAC = new Set(oldIssue.acceptanceCriteria || []);\n const newAC = new Set(newIssue.acceptanceCriteria || []);\n const addedAC = [...newAC].filter((ac) => !oldAC.has(ac));\n const removedAC = [...oldAC].filter((ac) => !newAC.has(ac));\n\n if (addedAC.length > 0 || removedAC.length > 0) {\n changes.push({\n field: 'acceptanceCriteria',\n oldValue: `${oldAC.size} criteria`,\n newValue: `${newAC.size} criteria (+${addedAC.length}/-${removedAC.length})`,\n significance: removedAC.length > 0 ? 'high' : 'low',\n });\n }\n\n // Compare tasks\n const oldTaskCount = oldIssue.tasks?.length || 0;\n const newTaskCount = newIssue.tasks?.length || 0;\n\n if (oldTaskCount !== newTaskCount) {\n changes.push({\n field: 'tasks',\n oldValue: oldTaskCount,\n newValue: newTaskCount,\n significance: 'medium',\n });\n }\n\n return changes;\n}\n\n/**\n * Diff two backlogs and return a comprehensive change summary\n */\nexport function diffBacklogs(oldBacklog: BacklogOutput, newBacklog: BacklogOutput): ChangeSummary {\n const changes: ChangeSummary = {\n added: 0,\n removed: 0,\n modified: 0,\n unchanged: 0,\n addedItems: [],\n removedItems: [],\n modifiedItems: [],\n hasRegressions: false,\n hasScopeCreep: false,\n hasEstimateInflation: false,\n };\n\n // Build ID maps for O(1) lookup\n const oldIssues = new Map(flattenIssues(oldBacklog).map((i) => [i.id, i]));\n const newIssues = new Map(flattenIssues(newBacklog).map((i) => [i.id, i]));\n\n // Find added issues\n for (const [id, issue] of newIssues) {\n if (!oldIssues.has(id)) {\n changes.added++;\n changes.addedItems.push(toChangeItem(issue));\n }\n }\n\n // Find removed issues (potential REGRESSIONS)\n for (const [id, issue] of oldIssues) {\n if (!newIssues.has(id)) {\n changes.removed++;\n changes.removedItems.push(toChangeItem(issue));\n\n // Flag regressions for critical/high priority items\n if (issue.priority === 'critical' || issue.priority === 'high') {\n changes.hasRegressions = true;\n }\n }\n }\n\n // Find modified issues\n for (const [id, newIssue] of newIssues) {\n const oldIssue = oldIssues.get(id);\n if (oldIssue) {\n const fieldChanges = diffIssue(oldIssue, newIssue);\n if (fieldChanges.length > 0) {\n changes.modified++;\n changes.modifiedItems.push({\n ...toChangeItem(newIssue),\n changes: fieldChanges,\n });\n } else {\n changes.unchanged++;\n }\n }\n }\n\n // Calculate estimate metrics\n changes.totalPointsBefore = sumEstimates(oldBacklog);\n changes.totalPointsAfter = sumEstimates(newBacklog);\n changes.pointsDelta = changes.totalPointsAfter - changes.totalPointsBefore;\n\n // Flag scope creep (>10% increase or 3+ new issues)\n const percentIncrease = changes.totalPointsBefore > 0\n ? (changes.pointsDelta / changes.totalPointsBefore) * 100\n : 0;\n\n if (changes.added >= 3 || percentIncrease > 10) {\n changes.hasScopeCreep = true;\n }\n\n // Flag estimate inflation (>20% increase)\n if (percentIncrease > 20) {\n changes.hasEstimateInflation = true;\n }\n\n return changes;\n}\n\n/**\n * Detect regressions (removed critical/high priority items)\n */\nexport function detectRegressions(\n baselineBacklog: BacklogOutput,\n currentBacklog: BacklogOutput,\n criticalOnly: boolean = false\n): ChangeItem[] {\n const baselineIssues = new Map(flattenIssues(baselineBacklog).map((i) => [i.id, i]));\n const currentIds = new Set(flattenIssues(currentBacklog).map((i) => i.id));\n\n const regressions: ChangeItem[] = [];\n\n for (const [id, issue] of baselineIssues) {\n if (!currentIds.has(id)) {\n if (criticalOnly) {\n if (issue.priority === 'critical' || issue.priority === 'high') {\n regressions.push(toChangeItem(issue));\n }\n } else {\n regressions.push(toChangeItem(issue));\n }\n }\n }\n\n return regressions;\n}\n\n/**\n * Track estimate inflation over multiple versions\n */\nexport function trackEstimateInflation(\n versions: Array<{ version: string; backlog: BacklogOutput; timestamp: string }>\n): Array<{\n version: string;\n timestamp: string;\n total: number;\n delta: number;\n percentChange: number;\n}> {\n const history: Array<{\n version: string;\n timestamp: string;\n total: number;\n delta: number;\n percentChange: number;\n }> = [];\n\n let previousTotal = 0;\n\n for (const { version, backlog, timestamp } of versions) {\n const total = sumEstimates(backlog);\n const delta = total - previousTotal;\n const percentChange = previousTotal > 0 ? (delta / previousTotal) * 100 : 0;\n\n history.push({\n version,\n timestamp,\n total,\n delta,\n percentChange,\n });\n\n previousTotal = total;\n }\n\n return history;\n}\n\n/**\n * Find issues with the largest estimate increases\n */\nexport function findTopInflators(\n oldBacklog: BacklogOutput,\n newBacklog: BacklogOutput,\n limit: number = 10\n): Array<{\n issue: ChangeItem;\n oldEstimate: number;\n newEstimate: number;\n delta: number;\n percentIncrease: number;\n}> {\n const oldIssues = new Map(flattenIssues(oldBacklog).map((i) => [i.id, i]));\n const newIssues = new Map(flattenIssues(newBacklog).map((i) => [i.id, i]));\n\n const inflators: Array<{\n issue: ChangeItem;\n oldEstimate: number;\n newEstimate: number;\n delta: number;\n percentIncrease: number;\n }> = [];\n\n for (const [id, newIssue] of newIssues) {\n const oldIssue = oldIssues.get(id);\n if (oldIssue) {\n const oldEstimate = typeof oldIssue.estimate === 'string' ? parseInt(oldIssue.estimate, 10) : (oldIssue.estimate || 0);\n const newEstimate = typeof newIssue.estimate === 'string' ? parseInt(newIssue.estimate, 10) : (newIssue.estimate || 0);\n const delta = newEstimate - oldEstimate;\n\n if (delta > 0) {\n const percentIncrease = oldEstimate > 0 ? (delta / oldEstimate) * 100 : 100;\n inflators.push({\n issue: toChangeItem(newIssue),\n oldEstimate,\n newEstimate,\n delta,\n percentIncrease,\n });\n }\n }\n }\n\n // Sort by delta descending\n inflators.sort((a, b) => b.delta - a.delta);\n\n return inflators.slice(0, limit);\n}\n\n/**\n * Get scope summary for a backlog\n */\nexport function getScopeSummary(backlog: BacklogOutput): {\n epics: number;\n issues: number;\n tasks: number;\n totalPoints: number;\n byCategory: Record<string, { issues: number; points: number }>;\n byPriority: Record<string, number>;\n} {\n const byCategory: Record<string, { issues: number; points: number }> = {};\n const byPriority: Record<string, number> = {};\n\n for (const epic of backlog.epics || []) {\n for (const issue of epic.issues || []) {\n const category = issue.category || epic.category || 'uncategorized';\n const priority = issue.priority || 'medium';\n const estimate = typeof issue.estimate === 'string' ? parseInt(issue.estimate, 10) : (issue.estimate || 0);\n\n if (!byCategory[category]) {\n byCategory[category] = { issues: 0, points: 0 };\n }\n byCategory[category].issues++;\n byCategory[category].points += estimate;\n\n byPriority[priority] = (byPriority[priority] || 0) + 1;\n }\n }\n\n return {\n epics: backlog.epics?.length || 0,\n issues: flattenIssues(backlog).length,\n tasks: countTasks(backlog),\n totalPoints: sumEstimates(backlog),\n byCategory,\n byPriority,\n };\n}\n","/**\n * Save Tool Output Utility\n *\n * Automatically saves tool output to the project's vasperaPM folder\n * with proper versioning and metadata headers.\n *\n * Includes tracking hooks for:\n * - JSON cache (for diffing)\n * - Audit event logging\n * - Change detection\n */\n\nimport { writeFileSync } from 'fs';\nimport { join } from 'path';\nimport {\n detectOutputPath,\n ensureOutputStructure,\n getCategoryPath,\n getNextVersion,\n logToolInvocation,\n} from './folder-manager.js';\nimport { wrapWithMetadata } from './metadata.js';\nimport type { OutputCategory } from '@vaspera/shared';\n\n// Tracking imports\nimport { saveToCache, loadFromCache, getPreviousVersion } from '../tracking/cache-manager.js';\nimport { appendAuditEvent, computeHash, type ChangeSummary } from '../tracking/audit-log.js';\nimport { diffBacklogs, type BacklogOutput } from '../tracking/diff-engine.js';\n\n/**\n * Options for saving tool output\n */\nexport interface SaveOptions {\n /** Project root path (from args or cwd) */\n projectRoot: string;\n /** Tool that generated the content */\n toolName: string;\n /** Category folder to save to */\n category: OutputCategory;\n /** Base filename (without version or extension) */\n filename: string;\n /** Generated content to save */\n content: string;\n /** File format */\n format: 'md' | 'json';\n /** Source files/inputs used to generate this output */\n inputs?: string[];\n /** Tokens consumed for generation */\n tokensUsed?: number;\n /** Structured data for caching (enables diffing) */\n structuredData?: unknown;\n /** Skip tracking for this save (default: false) */\n skipTracking?: boolean;\n}\n\n/**\n * Result of saving tool output\n */\nexport interface SaveResult {\n /** Full path to saved file */\n filePath: string;\n /** Version assigned (v1.0, v1.1, etc.) */\n version: string;\n /** Category folder used */\n category: OutputCategory;\n /** Relative path from project root */\n relativePath: string;\n /** Previous version (if exists) */\n previousVersion?: string;\n /** Change summary (if diffing was performed) */\n changes?: ChangeSummary;\n /** Audit event ID */\n auditEventId?: string;\n}\n\n/**\n * Tool to category mapping\n */\nexport const TOOL_CATEGORY_MAP: Record<string, { category: OutputCategory; filename: string }> = {\n synthesize_requirements: { category: 'requirements', filename: 'requirements' },\n synthesize_master_prd: { category: 'prd', filename: 'prd' },\n infer_prd_from_code: { category: 'prd', filename: 'inferred_prd' },\n review_prd: { category: 'prd', filename: 'prd_review' },\n explode_backlog: { category: 'backlog', filename: 'backlog' },\n sync_to_tracker: { category: 'backlog', filename: 'export' },\n generate_architecture: { category: 'architecture', filename: 'architecture' },\n generate_test_specs: { category: 'test-specs', filename: 'test_plan' },\n explain_codebase: { category: 'code-analysis', filename: 'codebase_overview' },\n reverse_engineer_user_flows: { category: 'code-analysis', filename: 'user_flows' },\n reverse_engineer_frontend: { category: 'code-analysis', filename: 'frontend_analysis' },\n validate_implementation: { category: 'code-analysis', filename: 'validation_report' },\n suggest_refactors: { category: 'code-analysis', filename: 'refactor_suggestions' },\n generate_api_docs: { category: 'api', filename: 'api_docs' },\n dependency_audit: { category: 'code-analysis', filename: 'dependency_audit' },\n estimate_migration: { category: 'code-analysis', filename: 'migration_estimate' },\n handoff_package: { category: 'handoff', filename: 'handoff' },\n // Phase 7: Powerhouse tools\n verify_docs_code: { category: 'code-analysis', filename: 'verification_report' },\n run_benchmark: { category: 'code-analysis', filename: 'benchmark_report' },\n analyze_git_freshness: { category: 'code-analysis', filename: 'freshness_report' },\n // Phase 8: Consolidation tools\n export_requirements: { category: 'requirements', filename: 'consolidated_requirements' },\n generate_complete_backlog: { category: 'backlog', filename: 'complete_backlog' },\n // Phase 9: DevOps tools\n generate_deployment_runbook: { category: 'handoff', filename: 'deployment_runbook' },\n // Phase 10: Traceability tools\n generate_changelog: { category: 'changelog', filename: 'changelog' },\n};\n\n/**\n * Save tool output to the project's vasperaPM folder\n *\n * @param options - Save options\n * @returns Save result with file path and version\n */\nexport function saveToolOutput(options: SaveOptions): SaveResult {\n const {\n projectRoot,\n toolName,\n category,\n filename,\n content,\n format,\n inputs = [],\n tokensUsed = 0,\n structuredData,\n skipTracking = false,\n } = options;\n\n // 1. Detect/create output folder structure\n const outputPath = detectOutputPath(projectRoot);\n ensureOutputStructure(outputPath);\n\n // 2. Get category path and next version number\n const categoryPath = getCategoryPath(outputPath, category);\n const version = getNextVersion(outputPath, category, filename);\n\n // 3. Build full filename with version prefix\n const fullFilename = `${filename}_v${version}.${format}`;\n const filePath = join(categoryPath, fullFilename);\n\n // 4. Add metadata header and save\n const contentWithMetadata = wrapWithMetadata(\n content,\n toolName,\n inputs,\n tokensUsed,\n version,\n 'complete' // status - all tool outputs are considered complete when saved\n );\n\n writeFileSync(filePath, contentWithMetadata, 'utf-8');\n\n // 5. Log to history\n logToolInvocation(outputPath, toolName, filePath, tokensUsed);\n\n // 6. Calculate relative path from project root\n const relativePath = filePath.replace(projectRoot, '').replace(/^\\//, '');\n\n // Initialize result\n const result: SaveResult = {\n filePath,\n version,\n category,\n relativePath,\n };\n\n // 7. Tracking: Save to cache and log audit event (if not skipped)\n if (!skipTracking && structuredData) {\n const inputHash = computeHash(JSON.stringify(inputs));\n const outputHash = computeHash(content);\n\n // Save structured data to cache for future diffing\n saveToCache(projectRoot, {\n category,\n filename,\n version,\n documentType: getDocumentType(toolName),\n toolName,\n inputHash,\n data: structuredData,\n });\n\n // Check for previous version and compute diff\n const previousVersion = getPreviousVersion(projectRoot, category, filename, version);\n let changes: ChangeSummary | undefined;\n\n if (previousVersion) {\n result.previousVersion = previousVersion;\n\n // Attempt to diff if this is a backlog document\n if (isBacklogDocument(toolName)) {\n const previousDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, previousVersion);\n if (previousDoc) {\n changes = diffBacklogs(previousDoc.data, structuredData as BacklogOutput);\n result.changes = changes;\n }\n }\n }\n\n // Append audit event\n const auditEvent = appendAuditEvent(projectRoot, {\n eventType: previousVersion ? 'update' : 'create',\n documentType: getDocumentType(toolName),\n documentPath: relativePath,\n version,\n previousVersion: previousVersion || undefined,\n toolName,\n tokensUsed,\n inputHash,\n outputHash,\n changes,\n });\n\n result.auditEventId = auditEvent.id;\n }\n\n return result;\n}\n\n/**\n * Get document type from tool name\n */\nfunction getDocumentType(toolName: string): string {\n const typeMap: Record<string, string> = {\n generate_complete_backlog: 'backlog',\n explode_backlog: 'backlog',\n sync_to_tracker: 'backlog_export',\n synthesize_requirements: 'requirements',\n synthesize_master_prd: 'prd',\n infer_prd_from_code: 'prd',\n generate_architecture: 'architecture',\n generate_test_specs: 'test_specs',\n generate_api_docs: 'api_docs',\n };\n\n return typeMap[toolName] || 'document';\n}\n\n/**\n * Check if a tool produces backlog documents (for diffing)\n */\nfunction isBacklogDocument(toolName: string): boolean {\n return ['generate_complete_backlog', 'explode_backlog'].includes(toolName);\n}\n\n/**\n * Get default save options for a tool\n *\n * @param toolName - Name of the tool\n * @returns Default category and filename for the tool\n */\nexport function getToolDefaults(toolName: string): { category: OutputCategory; filename: string } {\n return TOOL_CATEGORY_MAP[toolName] || { category: 'code-analysis', filename: toolName };\n}\n\n/**\n * Format the saved file path for display in tool output\n *\n * @param saved - Save result\n * @returns Formatted string for display\n */\nexport function formatSavedPath(saved: SaveResult): string {\n return `\\n\\n---\\n📁 **Saved to:** \\`${saved.relativePath}\\``;\n}\n","import type { TrackerItem, TrackerExportPackage, TargetPlatform } from '@vaspera/shared';\n\n/**\n * Platform-specific work item formats\n */\n\n// Azure DevOps Work Item\nexport interface ADOWorkItem {\n op: 'add';\n path: string;\n value: string | number;\n}\n\nexport interface ADOWorkItemBatch {\n method: 'PATCH';\n uri: string;\n headers: {\n 'Content-Type': string;\n };\n body: ADOWorkItem[];\n}\n\nexport interface ADOExport {\n $schema: string;\n metadata: TrackerExportPackage['metadata'];\n organization?: string;\n project?: string;\n workItems: ADOWorkItemBatch[];\n importInstructions: string;\n}\n\n// Jira Issue\nexport interface JiraIssue {\n fields: {\n project: { key: string };\n issuetype: { name: 'Epic' | 'Story' | 'Task' | 'Sub-task' | 'Bug' };\n summary: string;\n description: string;\n priority: { name: 'Highest' | 'High' | 'Medium' | 'Low' | 'Lowest' };\n labels?: string[];\n parent?: { key: string };\n [key: string]: unknown; // Custom fields\n };\n}\n\nexport interface JiraExport {\n metadata: TrackerExportPackage['metadata'];\n projectKey: string;\n issues: JiraIssue[];\n importInstructions: string;\n}\n\n// Linear Issue\nexport interface LinearIssue {\n title: string;\n description: string;\n priority: 0 | 1 | 2 | 3 | 4; // 0=None, 1=Urgent, 2=High, 3=Medium, 4=Low\n estimate?: number;\n labelIds?: string[];\n parentId?: string;\n}\n\nexport interface LinearExport {\n metadata: TrackerExportPackage['metadata'];\n teamId?: string;\n projectId?: string;\n issues: LinearIssue[];\n importInstructions: string;\n}\n\n// GitHub Issue\nexport interface GitHubIssue {\n title: string;\n body: string;\n labels: string[];\n milestone?: number;\n}\n\nexport interface GitHubExport {\n metadata: TrackerExportPackage['metadata'];\n owner?: string;\n repo?: string;\n issues: GitHubIssue[];\n importInstructions: string;\n}\n\n/**\n * Exporter interface (legacy)\n */\nexport interface TrackerExporter<T> {\n platform: TargetPlatform;\n export(items: TrackerItem[], projectKey: string): T;\n getImportInstructions(): string;\n}\n\n/**\n * Enhanced Platform Adapter interface (TD-004)\n *\n * Self-contained adapter that includes all platform-specific configuration.\n * Adding a new platform only requires creating a single file implementing this interface.\n */\nexport interface PlatformAdapter<TExport = unknown> {\n /** Platform identifier */\n readonly platform: TargetPlatform;\n\n /** Human-readable platform name */\n readonly displayName: string;\n\n /** Platform capabilities */\n readonly capabilities: {\n supportsHierarchy: boolean;\n supportsEstimates: boolean;\n supportsLabels: boolean;\n supportsPriority: boolean;\n supportsSubtasks: boolean;\n maxDescriptionLength?: number;\n };\n\n /** Convert universal TrackerItem to platform-specific format */\n export(items: TrackerItem[], projectKey: string): TExport;\n\n /** Get platform-specific import instructions */\n getImportInstructions(projectKey: string, itemCount: number): string;\n\n /** Map universal priority to platform-specific priority */\n mapPriority(priority: TrackerItem['priority']): unknown;\n\n /** Map universal work item type to platform-specific type */\n mapWorkItemType(type: TrackerItem['type']): string;\n\n /** Format estimate for platform */\n formatEstimate(value: number, unit: string): unknown;\n\n /** Validate items before export (optional) */\n validate?(items: TrackerItem[]): { valid: boolean; errors: string[] };\n}\n\n/**\n * Base class for platform adapters with common functionality\n */\nexport abstract class BasePlatformAdapter<TExport = unknown> implements PlatformAdapter<TExport> {\n abstract readonly platform: TargetPlatform;\n abstract readonly displayName: string;\n abstract readonly capabilities: PlatformAdapter['capabilities'];\n\n abstract export(items: TrackerItem[], projectKey: string): TExport;\n abstract getImportInstructions(projectKey: string, itemCount: number): string;\n abstract mapPriority(priority: TrackerItem['priority']): unknown;\n abstract mapWorkItemType(type: TrackerItem['type']): string;\n abstract formatEstimate(value: number, unit: string): unknown;\n\n /** Default validation - can be overridden */\n validate(items: TrackerItem[]): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n for (const item of items) {\n if (!item.title || item.title.trim().length === 0) {\n errors.push(`Item ${item.id}: Missing title`);\n }\n\n if (this.capabilities.maxDescriptionLength && item.description.length > this.capabilities.maxDescriptionLength) {\n errors.push(`Item ${item.id}: Description exceeds max length of ${this.capabilities.maxDescriptionLength}`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n /** Format description with acceptance criteria */\n protected formatDescription(item: TrackerItem): string {\n let desc = item.description;\n\n if (item.acceptanceCriteria.length > 0) {\n desc += '\\n\\n**Acceptance Criteria:**\\n';\n desc += item.acceptanceCriteria.map((c: string) => `- ${c}`).join('\\n');\n }\n\n if (item.dependencies.length > 0) {\n desc += `\\n\\n**Dependencies:** ${item.dependencies.join(', ')}`;\n }\n\n return desc;\n }\n}\n\n/**\n * Priority mappings\n */\nexport const PRIORITY_MAP = {\n jira: {\n critical: 'Highest',\n high: 'High',\n medium: 'Medium',\n low: 'Low',\n },\n ado: {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n },\n linear: {\n critical: 1, // Urgent\n high: 2,\n medium: 3,\n low: 4,\n },\n github: {\n critical: 'priority: critical',\n high: 'priority: high',\n medium: 'priority: medium',\n low: 'priority: low',\n },\n} as const;\n\n/**\n * Work item type mappings\n */\nexport const WORK_ITEM_TYPE_MAP = {\n jira: {\n epic: 'Epic',\n feature: 'Story',\n story: 'Story',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Sub-task',\n },\n ado: {\n // All process types - the actual type depends on the process template\n epic: 'Epic',\n feature: 'Feature',\n story: 'User Story', // Agile process\n issue: 'Issue', // Basic process\n pbi: 'Product Backlog Item', // Scrum process\n requirement: 'Requirement', // CMMI process\n task: 'Task',\n bug: 'Bug',\n subtask: 'Task',\n },\n linear: {\n epic: 'issue',\n feature: 'issue',\n story: 'issue',\n task: 'issue',\n bug: 'issue',\n subtask: 'sub-issue',\n },\n github: {\n epic: 'milestone',\n feature: 'issue',\n story: 'issue',\n task: 'issue',\n bug: 'issue',\n subtask: 'issue',\n },\n} as const;\n\n/**\n * Estimate formats\n */\nexport const ESTIMATE_FORMAT = {\n jira: (value: number, unit: string) => {\n if (unit === 'points') return value;\n if (unit === 'hours') return `${value}h`;\n if (unit === 'days') return `${value}d`;\n return value;\n },\n ado: (value: number, unit: string) => {\n if (unit === 'points') return value;\n if (unit === 'hours') return value;\n if (unit === 'days') return value * 8;\n return value;\n },\n linear: (value: number, unit: string) => {\n // Linear uses 0, 1, 2, 3, 5, 8\n if (unit === 'points') {\n const validPoints = [0, 1, 2, 3, 5, 8];\n return validPoints.reduce((prev, curr) =>\n Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev\n );\n }\n return Math.min(8, Math.ceil(value / 2));\n },\n github: (value: number, unit: string) => {\n // GitHub uses T-shirt sizes as labels\n if (unit === 'points') {\n if (value <= 1) return 'size: XS';\n if (value <= 3) return 'size: S';\n if (value <= 5) return 'size: M';\n if (value <= 8) return 'size: L';\n return 'size: XL';\n }\n if (unit === 'hours') {\n if (value <= 2) return 'size: XS';\n if (value <= 4) return 'size: S';\n if (value <= 8) return 'size: M';\n if (value <= 16) return 'size: L';\n return 'size: XL';\n }\n return 'size: M';\n },\n} as const;\n","import type { TrackerItem } from '@vaspera/shared';\nimport type { ADOExport, ADOWorkItem, ADOWorkItemBatch, TrackerExporter } from './types.js';\nimport { PRIORITY_MAP, WORK_ITEM_TYPE_MAP, ESTIMATE_FORMAT } from './types.js';\n\nconst VERSION = '0.2.1';\n\n/**\n * Azure DevOps Work Item Exporter\n *\n * Generates work items in ADO batch update format.\n * Can be imported via ADO REST API or Azure CLI.\n *\n * Hierarchy: Epic → Feature → User Story → Task\n */\nexport class ADOExporter implements TrackerExporter<ADOExport> {\n platform = 'ado' as const;\n\n private convertToHtml(markdown: string): string {\n // Basic markdown to HTML conversion for ADO\n return markdown\n .replace(/^### (.+)$/gm, '<h3>$1</h3>')\n .replace(/^## (.+)$/gm, '<h2>$1</h2>')\n .replace(/^# (.+)$/gm, '<h1>$1</h1>')\n .replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>')\n .replace(/\\*(.+?)\\*/g, '<em>$1</em>')\n .replace(/^- (.+)$/gm, '<li>$1</li>')\n .replace(/(<li>.*<\\/li>\\n?)+/g, '<ul>$&</ul>')\n .replace(/\\n/g, '<br>');\n }\n\n private formatAcceptanceCriteria(criteria: string[]): string {\n if (criteria.length === 0) return '';\n const list = criteria.map((c, i) => `<li>${c}</li>`).join('');\n return `<ul>${list}</ul>`;\n }\n\n private createWorkItemFields(item: TrackerItem, projectKey: string): ADOWorkItem[] {\n const fields: ADOWorkItem[] = [\n {\n op: 'add',\n path: '/fields/System.Title',\n value: item.title,\n },\n {\n op: 'add',\n path: '/fields/System.Description',\n value: this.convertToHtml(item.description),\n },\n {\n op: 'add',\n path: '/fields/Microsoft.VSTS.Common.Priority',\n value: PRIORITY_MAP.ado[item.priority],\n },\n {\n op: 'add',\n path: '/fields/System.AreaPath',\n value: projectKey,\n },\n ];\n\n // Add acceptance criteria for stories/issues/PBIs/requirements (all story-like types across ADO processes)\n const storyLikeTypes = ['story', 'issue', 'pbi', 'requirement'];\n if (storyLikeTypes.includes(item.type) && item.acceptanceCriteria.length > 0) {\n fields.push({\n op: 'add',\n path: '/fields/Microsoft.VSTS.Common.AcceptanceCriteria',\n value: this.formatAcceptanceCriteria(item.acceptanceCriteria),\n });\n }\n\n // Add story points for stories/issues/PBIs/requirements and features\n if (item.estimate && (storyLikeTypes.includes(item.type) || item.type === 'feature')) {\n fields.push({\n op: 'add',\n path: '/fields/Microsoft.VSTS.Scheduling.StoryPoints',\n value: ESTIMATE_FORMAT.ado(item.estimate.value, item.estimate.unit),\n });\n }\n\n // Add original estimate for tasks\n if (item.estimate && item.type === 'task') {\n fields.push({\n op: 'add',\n path: '/fields/Microsoft.VSTS.Scheduling.OriginalEstimate',\n value: ESTIMATE_FORMAT.ado(item.estimate.value, item.estimate.unit),\n });\n }\n\n // Add tags/labels\n if (item.labels.length > 0) {\n fields.push({\n op: 'add',\n path: '/fields/System.Tags',\n value: item.labels.join('; '),\n });\n }\n\n // Add assignee type as tag\n if (item.assigneeType) {\n const existingTags = fields.find((f) => f.path === '/fields/System.Tags');\n if (existingTags) {\n existingTags.value = `${existingTags.value}; team:${item.assigneeType}`;\n } else {\n fields.push({\n op: 'add',\n path: '/fields/System.Tags',\n value: `team:${item.assigneeType}`,\n });\n }\n }\n\n return fields;\n }\n\n export(items: TrackerItem[], projectKey: string): ADOExport {\n const workItems: ADOWorkItemBatch[] = items.map((item, index) => {\n const workItemType = WORK_ITEM_TYPE_MAP.ado[item.type];\n\n return {\n method: 'PATCH',\n uri: `/${projectKey}/_apis/wit/workitems/$${encodeURIComponent(workItemType)}?api-version=7.0`,\n headers: {\n 'Content-Type': 'application/json-patch+json',\n },\n body: this.createWorkItemFields(item, projectKey),\n };\n });\n\n return {\n $schema: 'https://dev.azure.com/schema/workitems/batch',\n metadata: {\n tool: 'sync_to_tracker',\n version: VERSION,\n generated: new Date().toISOString(),\n },\n project: projectKey,\n workItems,\n importInstructions: this.getImportInstructions(),\n };\n }\n\n getImportInstructions(): string {\n return `\n## Azure DevOps Import Instructions\n\n### Option 1: Azure CLI (Recommended)\n\n1. Install Azure CLI: https://docs.microsoft.com/cli/azure/install-azure-cli\n2. Install Azure DevOps extension:\n \\`\\`\\`bash\n az extension add --name azure-devops\n \\`\\`\\`\n3. Login and set organization:\n \\`\\`\\`bash\n az login\n az devops configure --defaults organization=https://dev.azure.com/YOUR_ORG project=YOUR_PROJECT\n \\`\\`\\`\n4. Create work items from this file:\n \\`\\`\\`bash\n # For each work item in the JSON, run:\n az boards work-item create --title \"TITLE\" --type \"User Story\" --description \"DESC\"\n \\`\\`\\`\n\n### Option 2: REST API\n\n1. Generate a Personal Access Token (PAT) at https://dev.azure.com/YOUR_ORG/_usersSettings/tokens\n2. Use the batch endpoint:\n \\`\\`\\`bash\n curl -X POST \\\\\n -H \"Content-Type: application/json\" \\\\\n -H \"Authorization: Basic :YOUR_PAT_BASE64\" \\\\\n -d @this-file.json \\\\\n \"https://dev.azure.com/YOUR_ORG/_apis/wit/$batch?api-version=7.0\"\n \\`\\`\\`\n\n### Option 3: Excel Import\n\n1. Open Azure DevOps → Boards → Work Items\n2. Click \"Import Work Items\"\n3. Download the Excel template\n4. Copy data from this JSON into the template\n5. Upload the completed Excel file\n\n### Hierarchy Setup\n\nAfter import, link items:\n- Epic → Features: Add \"Child\" link\n- Features → User Stories: Add \"Child\" link\n- User Stories → Tasks: Add \"Child\" link\n\nUse the \\`parentId\\` field to identify which items should be linked.\n`.trim();\n }\n}\n\nexport const adoExporter = new ADOExporter();\n","import type { TrackerItem } from '@vaspera/shared';\nimport type { JiraExport, JiraIssue, TrackerExporter } from './types.js';\nimport { PRIORITY_MAP, WORK_ITEM_TYPE_MAP, ESTIMATE_FORMAT } from './types.js';\n\nconst VERSION = '0.2.1';\n\n/**\n * Jira Issue Exporter\n *\n * Generates issues in Jira bulk import format.\n * Hierarchy: Epic → Story → Task → Sub-task\n */\nexport class JiraExporter implements TrackerExporter<JiraExport> {\n platform = 'jira' as const;\n\n private formatDescription(item: TrackerItem): string {\n let desc = item.description;\n\n if (item.acceptanceCriteria.length > 0) {\n desc += '\\n\\n*Acceptance Criteria:*\\n';\n desc += item.acceptanceCriteria.map((c) => `* ${c}`).join('\\n');\n }\n\n if (item.dependencies.length > 0) {\n desc += `\\n\\n*Dependencies:* ${item.dependencies.join(', ')}`;\n }\n\n return desc;\n }\n\n export(items: TrackerItem[], projectKey: string): JiraExport {\n const issues: JiraIssue[] = items.map((item) => {\n const issue: JiraIssue = {\n fields: {\n project: { key: projectKey },\n issuetype: { name: WORK_ITEM_TYPE_MAP.jira[item.type] as JiraIssue['fields']['issuetype']['name'] },\n summary: item.title,\n description: this.formatDescription(item),\n priority: { name: PRIORITY_MAP.jira[item.priority] as JiraIssue['fields']['priority']['name'] },\n labels: [...item.labels],\n },\n };\n\n // Add assignee type as label\n if (item.assigneeType) {\n issue.fields.labels?.push(`team:${item.assigneeType}`);\n }\n\n // Add story points (custom field - varies by instance)\n if (item.estimate && (item.type === 'story' || item.type === 'feature')) {\n issue.fields['customfield_10016'] = ESTIMATE_FORMAT.jira(item.estimate.value, item.estimate.unit);\n }\n\n // Add parent reference for sub-tasks\n if (item.parentId && item.type === 'subtask') {\n issue.fields.parent = { key: item.parentId };\n }\n\n return issue;\n });\n\n return {\n metadata: {\n tool: 'sync_to_tracker',\n version: VERSION,\n generated: new Date().toISOString(),\n },\n projectKey,\n issues,\n importInstructions: this.getImportInstructions(),\n };\n }\n\n getImportInstructions(): string {\n return `\n## Jira Import Instructions\n\n### Option 1: Jira REST API\n\n1. Get your Jira API token from: https://id.atlassian.com/manage-profile/security/api-tokens\n2. Create issues using the API:\n \\`\\`\\`bash\n curl -X POST \\\\\n -H \"Authorization: Basic YOUR_EMAIL:API_TOKEN_BASE64\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"fields\": {...}}' \\\\\n \"https://YOUR_DOMAIN.atlassian.net/rest/api/3/issue\"\n \\`\\`\\`\n\n### Option 2: CSV Import (Easier)\n\n1. Convert this JSON to CSV format\n2. Go to Jira → Project Settings → Import Issues\n3. Map the CSV columns to Jira fields\n4. Import the issues\n\n### Option 3: Jira CLI\n\n1. Install jira-cli: \\`npm install -g jira-cli\\`\n2. Configure: \\`jira-cli configure\\`\n3. Create issues: \\`jira-cli create-issue --json issue.json\\`\n\n### Hierarchy Setup\n\nAfter import, create links:\n- Epic → Stories: \"Epic Link\" field\n- Stories → Sub-tasks: Automatic via parent field\n\n### Custom Fields\n\n**Note:** Story points field ID (customfield_10016) varies by Jira instance.\nCheck your instance at: Admin → Issues → Custom Fields → Story Points\n`.trim();\n }\n}\n\nexport const jiraExporter = new JiraExporter();\n","import type { TrackerItem } from '@vaspera/shared';\nimport type { LinearExport, LinearIssue, TrackerExporter } from './types.js';\nimport { PRIORITY_MAP, ESTIMATE_FORMAT } from './types.js';\n\nconst VERSION = '0.2.1';\n\n/**\n * Linear Issue Exporter\n *\n * Generates issues in Linear's GraphQL mutation format.\n * Linear hierarchy: Project → Issue → Sub-issue\n */\nexport class LinearExporter implements TrackerExporter<LinearExport> {\n platform = 'linear' as const;\n\n private formatDescription(item: TrackerItem): string {\n let desc = item.description;\n\n if (item.acceptanceCriteria.length > 0) {\n desc += '\\n\\n## Acceptance Criteria\\n';\n desc += item.acceptanceCriteria.map((c) => `- [ ] ${c}`).join('\\n');\n }\n\n if (item.dependencies.length > 0) {\n desc += `\\n\\n**Dependencies:** ${item.dependencies.join(', ')}`;\n }\n\n return desc;\n }\n\n private buildLabels(item: TrackerItem): string[] {\n const labels: string[] = [...item.labels];\n\n // Add type as label since Linear doesn't have native type hierarchy\n if (item.type !== 'story') {\n labels.push(`type:${item.type}`);\n }\n\n // Add assignee type\n if (item.assigneeType) {\n labels.push(`team:${item.assigneeType}`);\n }\n\n return labels;\n }\n\n export(items: TrackerItem[], projectKey: string): LinearExport {\n const issues: LinearIssue[] = items.map((item) => {\n const issue: LinearIssue = {\n title: item.title,\n description: this.formatDescription(item),\n priority: PRIORITY_MAP.linear[item.priority] as LinearIssue['priority'],\n };\n\n // Add labels\n const labels = this.buildLabels(item);\n if (labels.length > 0) {\n issue.labelIds = labels; // These will need to be resolved to actual IDs\n }\n\n // Add estimate (Linear uses Fibonacci: 0, 1, 2, 3, 5, 8)\n if (item.estimate) {\n issue.estimate = ESTIMATE_FORMAT.linear(item.estimate.value, item.estimate.unit);\n }\n\n // Add parent reference for sub-issues\n if (item.parentId && item.type === 'subtask') {\n issue.parentId = item.parentId;\n }\n\n return issue;\n });\n\n return {\n metadata: {\n tool: 'sync_to_tracker',\n version: VERSION,\n generated: new Date().toISOString(),\n },\n projectId: projectKey,\n issues,\n importInstructions: this.getImportInstructions(),\n };\n }\n\n getImportInstructions(): string {\n return `\n## Linear Import Instructions\n\n### Option 1: Linear GraphQL API\n\n1. Get your Linear API key from: https://linear.app/settings/api\n2. Get your team ID and project ID from Linear settings\n3. Create issues using the GraphQL API:\n \\`\\`\\`bash\n curl -X POST \\\\\n -H \"Authorization: YOUR_API_KEY\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\"query\": \"mutation { issueCreate(input: {...}) { issue { id } } }\"}' \\\\\n \"https://api.linear.app/graphql\"\n \\`\\`\\`\n\n### Option 2: Linear SDK (Node.js)\n\n\\`\\`\\`typescript\nimport { LinearClient } from '@linear/sdk';\n\nconst client = new LinearClient({ apiKey: 'YOUR_API_KEY' });\n\n// Create issue\nconst issue = await client.createIssue({\n teamId: 'TEAM_ID',\n title: issue.title,\n description: issue.description,\n priority: issue.priority,\n estimate: issue.estimate,\n});\n\\`\\`\\`\n\n### Option 3: CSV Import\n\n1. Export this JSON to CSV format\n2. Go to Linear → Settings → Import → CSV\n3. Map columns to Linear fields\n4. Import issues\n\n### Labels Setup\n\nBefore importing, create these labels in Linear:\n- **Type labels:** type:epic, type:feature, type:task, type:bug\n- **Team labels:** team:frontend, team:backend, team:fullstack, team:design, team:qa\n- **Priority labels:** (Linear handles priority natively)\n\n### Estimate Points\n\nLinear uses Fibonacci estimates: 0, 1, 2, 3, 5, 8\nEstimates in this export have been converted to Linear's scale.\n\n### Sub-issues\n\nAfter initial import, link sub-issues to their parents:\n- Open the parent issue\n- Add sub-issues via the \"+\" button or API\n`.trim();\n }\n}\n\nexport const linearExporter = new LinearExporter();\n","import type { TrackerItem } from '@vaspera/shared';\nimport type { GitHubExport, GitHubIssue, TrackerExporter } from './types.js';\nimport { PRIORITY_MAP, ESTIMATE_FORMAT } from './types.js';\n\nconst VERSION = '0.2.1';\n\n/**\n * GitHub Issues Exporter\n *\n * Generates issues in GitHub REST API format.\n * GitHub hierarchy: Milestone (epic) → Issue → Task list items\n */\nexport class GitHubExporter implements TrackerExporter<GitHubExport> {\n platform = 'github' as const;\n\n private formatBody(item: TrackerItem): string {\n let body = item.description;\n\n if (item.acceptanceCriteria.length > 0) {\n body += '\\n\\n## Acceptance Criteria\\n';\n body += item.acceptanceCriteria.map((c) => `- [ ] ${c}`).join('\\n');\n }\n\n if (item.dependencies.length > 0) {\n body += `\\n\\n## Dependencies\\n`;\n body += item.dependencies.map((d) => `- Blocked by: ${d}`).join('\\n');\n }\n\n // Add VasperaPM reference\n if (item.id) {\n body += `\\n\\n---\\n_VasperaPM ID: ${item.id}_`;\n }\n\n return body;\n }\n\n private buildLabels(item: TrackerItem): string[] {\n const labels: string[] = [...item.labels];\n\n // Add type label\n const typeLabels: Record<string, string> = {\n epic: 'type: epic',\n feature: 'type: feature',\n story: 'type: story',\n task: 'type: task',\n bug: 'type: bug',\n subtask: 'type: subtask',\n };\n labels.push(typeLabels[item.type] || 'type: task');\n\n // Add priority label\n labels.push(PRIORITY_MAP.github[item.priority]);\n\n // Add estimate size label\n if (item.estimate) {\n labels.push(ESTIMATE_FORMAT.github(item.estimate.value, item.estimate.unit));\n }\n\n // Add team label\n if (item.assigneeType) {\n labels.push(`team: ${item.assigneeType}`);\n }\n\n return labels;\n }\n\n export(items: TrackerItem[], projectKey: string): GitHubExport {\n const issues: GitHubIssue[] = [];\n const milestones: Map<string, TrackerItem> = new Map();\n\n // First pass: identify epics as milestones\n for (const item of items) {\n if (item.type === 'epic') {\n milestones.set(item.id, item);\n }\n }\n\n // Second pass: create issues\n for (const item of items) {\n if (item.type === 'epic') {\n // Epics become milestones, not issues\n // They'll be created via separate API call\n continue;\n }\n\n const issue: GitHubIssue = {\n title: item.title,\n body: this.formatBody(item),\n labels: this.buildLabels(item),\n };\n\n // Link to milestone if parent is an epic\n if (item.parentId && milestones.has(item.parentId)) {\n // Milestone number will be set after milestone creation\n issue.milestone = undefined; // Placeholder\n }\n\n issues.push(issue);\n }\n\n return {\n metadata: {\n tool: 'sync_to_tracker',\n version: VERSION,\n generated: new Date().toISOString(),\n },\n owner: projectKey.split('/')[0],\n repo: projectKey.split('/')[1] || projectKey,\n issues,\n importInstructions: this.getImportInstructions(),\n };\n }\n\n getImportInstructions(): string {\n return `\n## GitHub Import Instructions\n\n### Option 1: GitHub CLI (Recommended)\n\n1. Install GitHub CLI: https://cli.github.com/\n2. Authenticate: \\`gh auth login\\`\n3. Create issues:\n \\`\\`\\`bash\n gh issue create --title \"Issue title\" \\\\\n --body \"Issue body\" \\\\\n --label \"type: feature,priority: high\" \\\\\n --repo owner/repo\n \\`\\`\\`\n\n### Option 2: GitHub REST API\n\n\\`\\`\\`bash\ncurl -X POST \\\\\n -H \"Authorization: token YOUR_TOKEN\" \\\\\n -H \"Accept: application/vnd.github.v3+json\" \\\\\n -d '{\"title\": \"Issue title\", \"body\": \"...\", \"labels\": [...]}' \\\\\n \"https://api.github.com/repos/owner/repo/issues\"\n\\`\\`\\`\n\n### Option 3: GitHub Actions Workflow\n\nCreate a workflow that reads this JSON and creates issues:\n\n\\`\\`\\`yaml\nname: Import VasperaPM Issues\non: workflow_dispatch\njobs:\n import:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Create issues\n uses: actions/github-script@v7\n with:\n script: |\n const issues = require('./issues.json').issues;\n for (const issue of issues) {\n await github.rest.issues.create({\n owner: context.repo.owner,\n repo: context.repo.repo,\n ...issue\n });\n }\n\\`\\`\\`\n\n### Labels Setup\n\nBefore importing, create these labels in your repository:\n- **Type:** type: epic, type: feature, type: story, type: task, type: bug\n- **Priority:** priority: critical, priority: high, priority: medium, priority: low\n- **Size:** size: XS, size: S, size: M, size: L, size: XL\n- **Team:** team: frontend, team: backend, team: fullstack, team: design, team: qa\n\n### Epics as Milestones\n\nEpics are represented as GitHub Milestones:\n1. Create milestones first via Settings → Milestones\n2. Then create issues and assign them to milestones\n\n### Sub-tasks\n\nGitHub doesn't have native sub-tasks. Use:\n- Task lists in issue body (checkboxes)\n- Issue references (#123)\n- Labels to indicate relationship\n\n### Project Boards\n\nAfter import, organize issues in GitHub Projects:\n1. Create a new Project (V2)\n2. Add imported issues\n3. Set up custom fields for estimates, sprints, etc.\n`.trim();\n }\n}\n\nexport const githubExporter = new GitHubExporter();\n","/**\n * Tracker Exporters\n *\n * Platform-specific exporters for sync_to_tracker tool.\n * Converts TrackerItem[] to platform-native import formats.\n *\n * TD-004: Platform Adapter Registry\n * - Self-registering adapters\n * - Adding new platforms requires only creating a single file\n */\n\n// Types\nexport * from './types.js';\nimport type { PlatformAdapter, TrackerExporter } from './types.js';\n\n// Exporters (legacy)\nexport { ADOExporter, adoExporter } from './ado.js';\nexport { JiraExporter, jiraExporter } from './jira.js';\nexport { LinearExporter, linearExporter } from './linear.js';\nexport { GitHubExporter, githubExporter } from './github.js';\n\n// Re-export for convenience\nimport { adoExporter } from './ado.js';\nimport { jiraExporter } from './jira.js';\nimport { linearExporter } from './linear.js';\nimport { githubExporter } from './github.js';\nimport type { TargetPlatform } from '@vaspera/shared';\n\n// ============================================================================\n// Platform Adapter Registry (TD-004)\n// ============================================================================\n\n/**\n * Registry of all platform adapters\n * Adapters self-register using registerAdapter()\n */\nconst adapterRegistry = new Map<TargetPlatform, PlatformAdapter>();\n\n/**\n * Register a platform adapter\n * Call this in each adapter file to self-register\n */\nexport function registerAdapter(adapter: PlatformAdapter): void {\n if (adapterRegistry.has(adapter.platform)) {\n console.warn(`[AdapterRegistry] Overwriting existing adapter for ${adapter.platform}`);\n }\n adapterRegistry.set(adapter.platform, adapter);\n console.log(`[AdapterRegistry] Registered adapter: ${adapter.displayName} (${adapter.platform})`);\n}\n\n/**\n * Get adapter by platform name\n * Returns the new PlatformAdapter if available, falls back to legacy exporter\n */\nexport function getAdapter(platform: TargetPlatform): PlatformAdapter | TrackerExporter<unknown> {\n const adapter = adapterRegistry.get(platform);\n if (adapter) {\n return adapter;\n }\n // Fall back to legacy exporters\n return getExporter(platform);\n}\n\n/**\n * Get all registered adapters\n */\nexport function getRegisteredAdapters(): PlatformAdapter[] {\n return Array.from(adapterRegistry.values());\n}\n\n/**\n * Get all supported platforms (from both registry and legacy)\n */\nexport function getSupportedPlatforms(): TargetPlatform[] {\n const platforms = new Set<TargetPlatform>([\n ...adapterRegistry.keys(),\n ...Object.keys(exporters) as TargetPlatform[],\n ]);\n return Array.from(platforms);\n}\n\n/**\n * Check if a platform is supported\n */\nexport function isPlatformSupported(platform: string): platform is TargetPlatform {\n return adapterRegistry.has(platform as TargetPlatform) || platform in exporters;\n}\n\n// ============================================================================\n// Legacy Exporter Functions (backward compatibility)\n// ============================================================================\n\n/**\n * Get exporter by platform name (legacy)\n */\nexport function getExporter(platform: TargetPlatform) {\n switch (platform) {\n case 'ado':\n return adoExporter;\n case 'jira':\n return jiraExporter;\n case 'linear':\n return linearExporter;\n case 'github':\n return githubExporter;\n default:\n throw new Error(`Unknown platform: ${platform}`);\n }\n}\n\n/**\n * All available exporters (legacy)\n */\nexport const exporters = {\n ado: adoExporter,\n jira: jiraExporter,\n linear: linearExporter,\n github: githubExporter,\n} as const;\n","/**\n * VasperaPM Output Module\n *\n * Handles output folder organization, metadata injection,\n * platform-specific export formatting, and auto-saving tool output.\n */\n\n// Folder management\nexport {\n detectOutputPath,\n initializeOutputFolder,\n ensureOutputStructure,\n getCategoryPath,\n getNextVersion,\n logToolInvocation,\n hasOutputFolder,\n listCategoryFiles,\n getConfig,\n updateConfig,\n} from './folder-manager.js';\n\n// Metadata\nexport {\n generateMetadataHeader,\n generateJsonMetadata,\n parseMetadataHeader,\n wrapWithMetadata,\n} from './metadata.js';\n\n// Save output utility (for tools to auto-save)\nexport {\n saveToolOutput,\n getToolDefaults,\n formatSavedPath,\n TOOL_CATEGORY_MAP,\n type SaveOptions,\n type SaveResult,\n} from './save-output.js';\n\n// Exporters\nexport * from './exporters/index.js';\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * Component library guidance for frontend story generation\n */\nconst LIBRARY_GUIDANCE: Record<string, string> = {\n shadcn:\n 'Use shadcn/ui components (Button, Card, Dialog, Input, etc.) built on Radix UI primitives. Reference Tailwind CSS classes.',\n mui: 'Use Material-UI components with sx prop styling. Reference MuiThemeProvider patterns.',\n chakra: 'Use Chakra UI components with theme tokens. Reference styled-components patterns.',\n antd: 'Use Ant Design components. Reference antd design system patterns.',\n custom: 'Use generic component descriptions without framework specifics.',\n unknown: 'Generate framework-agnostic component specifications.',\n};\n\n/**\n * explode_backlog tool - Breaks down high-level features into detailed user stories\n */\nexport const explodeBacklogTool: ToolDefinition = {\n tool: {\n name: 'explode_backlog',\n description: `Break down high-level features or epics into detailed, actionable user stories.\n\nTakes a feature description and generates:\n- User stories with acceptance criteria\n- Story point estimates\n- Priority recommendations\n- Dependencies between stories\n- Frontend component stories (when includeFrontend: true)\n\nBest for: Converting feature ideas into sprint-ready backlog items.`,\n inputSchema: {\n type: 'object',\n properties: {\n feature: {\n type: 'string',\n description: 'The feature or epic to break down into user stories',\n },\n context: {\n type: 'string',\n description: 'Optional context about the product, tech stack, or constraints',\n },\n format: {\n type: 'string',\n enum: ['markdown', 'json', 'jira', 'linear'],\n default: 'markdown',\n description: 'Output format for the stories',\n },\n maxStories: {\n type: 'number',\n default: 10,\n description: 'Maximum number of stories to generate',\n },\n includeFrontend: {\n type: 'boolean',\n default: false,\n description: 'Include frontend development stories alongside feature stories',\n },\n frontendStyle: {\n type: 'string',\n enum: ['behavior', 'component', 'full'],\n default: 'full',\n description:\n 'Focus of frontend stories: behavior (acceptance criteria only), component (with specs/states), full (includes API contracts/validation)',\n },\n componentLibrary: {\n type: 'string',\n enum: ['shadcn', 'mui', 'chakra', 'antd', 'custom', 'unknown'],\n default: 'custom',\n description: 'Component library for story templates',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['feature'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const feature = args.feature as string;\n const context = args.context as string | undefined;\n const format = (args.format as string) || 'markdown';\n const maxStories = (args.maxStories as number) || 10;\n const includeFrontend = (args.includeFrontend as boolean) ?? false;\n const frontendStyle = (args.frontendStyle as string) || 'full';\n const componentLibrary = (args.componentLibrary as string) || 'custom';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!feature || feature.trim().length === 0) {\n return errorResult('Feature description is required');\n }\n\n // Build frontend guidance section when includeFrontend is true\n const frontendGuidance = includeFrontend\n ? `\n\n## Frontend Story Guidelines\nGenerate frontend development stories with the following structure:\n\n**Style Level: ${frontendStyle}**\n${frontendStyle === 'behavior' ? '- Focus on user-visible behavior and acceptance criteria only' : ''}\n${\n frontendStyle === 'component' || frontendStyle === 'full'\n ? `- Include component specifications:\n - Component name and type (page/component/layout/modal)\n - States: idle, loading, error, success, empty\n - Props with TypeScript types\n - Events and handlers`\n : ''\n}\n${\n frontendStyle === 'full'\n ? `- Include API contracts:\n - Endpoint, method, request/response shapes\n- Include validation rules:\n - Field, rules (required, format, min/max length)\n- Include responsive behavior:\n - Mobile, tablet, desktop layouts`\n : ''\n}\n\n**Component Library: ${componentLibrary}**\n${LIBRARY_GUIDANCE[componentLibrary] || LIBRARY_GUIDANCE.custom}\n\n**Accessibility Requirements:**\n- All interactive elements must have proper ARIA labels\n- Form inputs must have associated labels\n- Error states must be announced to screen readers\n- Focus management for modals and dialogs\n\nFor each frontend story, output a JSON object with this structure:\n\\`\\`\\`json\n{\n \"title\": \"Component/Feature title\",\n \"type\": \"frontend\",\n \"priority\": \"High|Medium|Low\",\n \"story_points\": 1|2|3|5|8|13,\n \"componentSpec\": {\n \"name\": \"ComponentName\",\n \"type\": \"page|component|layout|modal\",\n \"states\": [\"idle\", \"loading\", \"error\", \"success\"],\n \"props\": [{ \"name\": \"propName\", \"type\": \"TypeScript type\", \"required\": true }],\n \"events\": [{ \"name\": \"onEvent\", \"payload\": \"{ ... }\" }]\n },\n \"behavior\": {\n \"userFlow\": [\"step 1\", \"step 2\"],\n \"edgeCases\": [\"edge case 1\"],\n \"accessibility\": [\"a11y requirement 1\"]\n }${frontendStyle === 'full' ? `,\n \"apiContract\": {\n \"endpoint\": \"/api/...\",\n \"method\": \"GET|POST|PUT|DELETE\",\n \"requestShape\": \"{ ... }\",\n \"responseShape\": \"{ ... }\"\n },\n \"validation\": [\n { \"field\": \"fieldName\", \"rules\": [\"required\", \"email format\", \"min 8 chars\"] }\n ],\n \"responsive\": {\n \"mobile\": \"description\",\n \"tablet\": \"description\",\n \"desktop\": \"description\"\n }` : ''},\n \"acceptanceCriteria\": [\"Given/When/Then...\"]\n}\n\\`\\`\\`\n`\n : '';\n\n const systemPrompt = `You are an expert product manager and agile coach. Your task is to break down features into well-structured user stories.\n\nFor each user story, provide:\n1. A clear title following the format: \"As a [user], I want [goal] so that [benefit]\"\n2. Detailed acceptance criteria (at least 3 per story)\n3. Story point estimate (1, 2, 3, 5, 8, or 13)\n4. Priority (High, Medium, Low)\n5. Any dependencies on other stories\n\nGuidelines:\n- Stories should be independent when possible\n- Each story should be completable in a single sprint\n- Include edge cases and error handling in acceptance criteria\n- Consider both happy path and error scenarios\n- Stories should be testable\n${frontendGuidance}\n${context ? `Product Context: ${context}` : ''}`;\n\n const userMessage = `Break down the following feature into ${maxStories} or fewer detailed user stories:\n\nFeature: ${feature}\n${\n includeFrontend\n ? `\nInclude both backend/API stories AND frontend component stories.\nGenerate at least ${Math.ceil(maxStories * 0.4)} frontend stories with component specs.`\n : ''\n}\n${\n format === 'json'\n ? 'Output as a JSON array of story objects.'\n : format === 'jira'\n ? 'Format for Jira import (CSV-compatible).'\n : format === 'linear'\n ? 'Format for Linear import.'\n : 'Output in clean markdown format with embedded JSON for frontend component specs.'\n}`;\n\n // Increase token budget when generating frontend stories\n const maxTokens = includeFrontend ? 8192 : 4096;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('explode_backlog');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'explode_backlog',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: ['feature'],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate user stories: ${message}`);\n }\n },\n\n requiredScope: 'tools:explode_backlog',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * infer_prd_from_code tool - Generates a PRD from existing codebase\n */\nexport const inferPrdTool: ToolDefinition = {\n tool: {\n name: 'infer_prd_from_code',\n description: `Analyze code and generate a Product Requirements Document (PRD).\n\nTakes code snippets, file structures, or repository descriptions and infers:\n- Product overview and purpose\n- Feature list with descriptions\n- User personas and use cases\n- Technical requirements\n- Non-functional requirements\n\nBest for: Documenting existing products or understanding inherited codebases.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'Code snippets, file structure, or repository content to analyze',\n },\n repoDescription: {\n type: 'string',\n description: 'Optional description of the repository or project',\n },\n techStack: {\n type: 'string',\n description: 'Technology stack used (e.g., \"Next.js, TypeScript, PostgreSQL\")',\n },\n focusAreas: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific areas to focus on (e.g., [\"authentication\", \"payments\"])',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['code'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const code = args.code as string;\n const repoDescription = args.repoDescription as string | undefined;\n const techStack = args.techStack as string | undefined;\n const focusAreas = args.focusAreas as string[] | undefined;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!code || code.trim().length === 0) {\n return errorResult('Code content is required');\n }\n\n const systemPrompt = `You are an expert product manager who specializes in reverse-engineering products from code. Your task is to analyze code and generate a comprehensive PRD.\n\nThe PRD should include:\n1. **Product Overview** - What the product does and its purpose\n2. **Target Users** - Who uses this product and why\n3. **Core Features** - List of main features with descriptions\n4. **User Stories** - Key user journeys\n5. **Technical Requirements** - Architecture and technical constraints\n6. **Non-Functional Requirements** - Performance, security, scalability\n7. **Future Considerations** - Potential improvements or extensions\n\nGuidelines:\n- Infer purpose from code patterns and naming conventions\n- Identify API endpoints and their purposes\n- Note database schema and data models\n- Consider error handling and edge cases\n- Look for authentication/authorization patterns\n\n${techStack ? `Tech Stack: ${techStack}` : ''}\n${repoDescription ? `Repository Description: ${repoDescription}` : ''}\n${focusAreas?.length ? `Focus Areas: ${focusAreas.join(', ')}` : ''}`;\n\n const userMessage = `Analyze the following code and generate a comprehensive PRD:\n\n\\`\\`\\`\n${code.length > 15000 ? code.substring(0, 15000) + '\\n... [truncated]' : code}\n\\`\\`\\`\n\nGenerate a detailed PRD in markdown format.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 4096,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('infer_prd_from_code');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'infer_prd_from_code',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: focusAreas || ['code'],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate PRD: ${message}`);\n }\n },\n\n requiredScope: 'tools:infer_prd',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * synthesize_master_prd tool - Combines multiple documents into a unified PRD\n */\nexport const synthesizePrdTool: ToolDefinition = {\n tool: {\n name: 'synthesize_master_prd',\n description: `Synthesize multiple input documents into a unified Master PRD.\n\nTakes multiple sources (meeting notes, emails, specs, designs) and creates:\n- Unified product vision\n- Consolidated requirements\n- Prioritized feature list\n- Clear success metrics\n- Risk assessment\n\nBest for: Creating a single source of truth from scattered documentation.`,\n inputSchema: {\n type: 'object',\n properties: {\n documents: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n content: { type: 'string' },\n type: {\n type: 'string',\n enum: ['meeting_notes', 'email', 'spec', 'design', 'feedback', 'other'],\n },\n },\n required: ['content'],\n },\n description: 'Array of documents to synthesize',\n },\n productName: {\n type: 'string',\n description: 'Name of the product',\n },\n targetAudience: {\n type: 'string',\n description: 'Description of the target users',\n },\n constraints: {\n type: 'string',\n description: 'Any constraints (timeline, budget, tech limitations)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['documents'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const documents = args.documents as Array<{ title?: string; content: string; type?: string }>;\n const productName = args.productName as string | undefined;\n const targetAudience = args.targetAudience as string | undefined;\n const constraints = args.constraints as string | undefined;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!documents || documents.length === 0) {\n return errorResult('At least one document is required');\n }\n\n const systemPrompt = `You are an expert product manager who excels at synthesizing scattered information into clear, actionable PRDs.\n\nCreate a Master PRD with the following sections:\n1. **Executive Summary** - High-level overview\n2. **Product Vision** - What we're building and why\n3. **Target Users** - Who benefits and their needs\n4. **Goals & Success Metrics** - How we measure success\n5. **Features & Requirements** - Detailed feature list with priorities\n6. **User Journeys** - Key workflows\n7. **Technical Considerations** - Architecture implications\n8. **Risks & Mitigations** - What could go wrong\n9. **Timeline & Milestones** - High-level roadmap\n10. **Open Questions** - Items needing clarification\n\nGuidelines:\n- Resolve contradictions between documents by noting them\n- Extract implicit requirements from feedback and discussions\n- Identify gaps that need stakeholder input\n- Prioritize based on user impact and business value\n\n${productName ? `Product Name: ${productName}` : ''}\n${targetAudience ? `Target Audience: ${targetAudience}` : ''}\n${constraints ? `Constraints: ${constraints}` : ''}`;\n\n // Format documents for the prompt\n const formattedDocs = documents.map((doc, i) => {\n const title = doc.title || `Document ${i + 1}`;\n const type = doc.type || 'other';\n return `### ${title} (${type})\\n${doc.content}`;\n }).join('\\n\\n---\\n\\n');\n\n const userMessage = `Synthesize the following documents into a comprehensive Master PRD:\n\n${formattedDocs.length > 20000 ? formattedDocs.substring(0, 20000) + '\\n... [truncated]' : formattedDocs}\n\nCreate a unified PRD that captures all requirements and resolves any conflicts.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('synthesize_master_prd');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'synthesize_master_prd',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: documents.map((d) => d.title || d.type || 'document'),\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to synthesize PRD: ${message}`);\n }\n },\n\n requiredScope: 'tools:synthesize_prd',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, resolve, relative } from 'path';\n\n// ============================================================================\n// Schema Discovery\n// ============================================================================\n\ninterface SchemaFile {\n path: string;\n relativePath: string;\n type: 'prisma' | 'drizzle' | 'typeorm' | 'sql' | 'mongoose' | 'supabase' | 'other';\n content: string;\n}\n\n/**\n * Auto-discover database schema files in a repository\n */\nfunction discoverSchemaFiles(repoPath: string): SchemaFile[] {\n const schemas: SchemaFile[] = [];\n const absoluteRoot = resolve(repoPath);\n\n // Schema file patterns to look for\n const patterns = [\n // Prisma\n { glob: '**/prisma/schema.prisma', type: 'prisma' as const },\n { glob: '**/schema.prisma', type: 'prisma' as const },\n // Drizzle\n { glob: '**/drizzle/schema.ts', type: 'drizzle' as const },\n { glob: '**/db/schema.ts', type: 'drizzle' as const },\n { glob: '**/schema/*.ts', type: 'drizzle' as const },\n // TypeORM entities\n { glob: '**/entities/*.ts', type: 'typeorm' as const },\n { glob: '**/entity/*.ts', type: 'typeorm' as const },\n // SQL migrations\n { glob: '**/migrations/*.sql', type: 'sql' as const },\n { glob: '**/supabase/migrations/*.sql', type: 'supabase' as const },\n // Mongoose models\n { glob: '**/models/*.ts', type: 'mongoose' as const },\n { glob: '**/models/*.js', type: 'mongoose' as const },\n ];\n\n // Simple recursive file finder\n function findFiles(dir: string, pattern: string, type: SchemaFile['type']): void {\n if (!existsSync(dir)) return;\n\n try {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n\n // Skip node_modules and hidden directories\n if (entry === 'node_modules' || entry.startsWith('.')) continue;\n\n try {\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n findFiles(fullPath, pattern, type);\n } else if (stat.isFile()) {\n // Check if file matches pattern\n const relativePath = relative(absoluteRoot, fullPath);\n if (matchPattern(relativePath, pattern)) {\n const content = readFileSync(fullPath, 'utf-8');\n // Only include files that look like schemas\n if (isSchemaContent(content, type)) {\n schemas.push({\n path: fullPath,\n relativePath,\n type,\n content: content.length > 5000 ? content.substring(0, 5000) + '\\n... [truncated]' : content,\n });\n }\n }\n }\n } catch {\n // Skip files we can't read\n }\n }\n } catch {\n // Skip directories we can't read\n }\n }\n\n // Simple glob pattern matching\n function matchPattern(filePath: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*')\n .replace(/\\//g, '\\\\/');\n return new RegExp(regexPattern).test(filePath);\n }\n\n // Check if file content looks like a schema\n function isSchemaContent(content: string, type: SchemaFile['type']): boolean {\n switch (type) {\n case 'prisma':\n return content.includes('model ') || content.includes('datasource ');\n case 'drizzle':\n return content.includes('pgTable') || content.includes('sqliteTable') || content.includes('mysqlTable');\n case 'typeorm':\n return content.includes('@Entity') || content.includes('@Column');\n case 'sql':\n return content.includes('CREATE TABLE') || content.includes('ALTER TABLE');\n case 'supabase':\n return content.includes('CREATE TABLE') || content.includes('create table');\n case 'mongoose':\n return content.includes('Schema(') || content.includes('new Schema');\n default:\n return true;\n }\n }\n\n // Search for each pattern\n for (const { glob, type } of patterns) {\n findFiles(absoluteRoot, glob, type);\n }\n\n return schemas;\n}\n\n/**\n * Format discovered schemas for the AI prompt\n */\nfunction formatSchemasForPrompt(schemas: SchemaFile[]): string {\n if (schemas.length === 0) return '';\n\n const lines: string[] = ['## Discovered Database Schemas\\n'];\n\n for (const schema of schemas) {\n lines.push(`### ${schema.relativePath} (${schema.type})`);\n lines.push('```' + (schema.type === 'prisma' ? 'prisma' : schema.type === 'sql' || schema.type === 'supabase' ? 'sql' : 'typescript'));\n lines.push(schema.content);\n lines.push('```\\n');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * generate_architecture tool - Creates technical architecture from requirements\n */\nexport const generateArchitectureTool: ToolDefinition = {\n tool: {\n name: 'generate_architecture',\n description: `Generate a technical architecture document from product requirements.\n\nTakes a PRD or feature description and creates:\n- System architecture diagram (in Mermaid)\n- Component breakdown\n- Data models and schemas\n- API design recommendations\n- Technology stack suggestions\n- Scalability considerations\n\nSupports two modes:\n1. **File mode** (recommended): Provide repoPath to auto-discover database schemas (Prisma, Drizzle, SQL, TypeORM, Mongoose)\n2. **Manual mode**: Provide requirements text directly\n\nBest for: Translating product requirements into technical specifications.`,\n inputSchema: {\n type: 'object',\n properties: {\n requirements: {\n type: 'string',\n description: 'Product requirements or PRD content',\n },\n repoPath: {\n type: 'string',\n description: 'Path to repository for auto-discovery of database schemas (Prisma, Drizzle, SQL migrations, TypeORM entities)',\n },\n existingStack: {\n type: 'string',\n description: 'Existing technology stack to build upon',\n },\n constraints: {\n type: 'object',\n properties: {\n budget: { type: 'string' },\n timeline: { type: 'string' },\n team: { type: 'string' },\n compliance: { type: 'array', items: { type: 'string' } },\n },\n description: 'Technical and business constraints',\n },\n focus: {\n type: 'string',\n enum: ['backend', 'frontend', 'fullstack', 'infrastructure', 'data'],\n default: 'fullstack',\n description: 'Architecture focus area',\n },\n includeDiagrams: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['system', 'database', 'api', 'sequence', 'deployment'],\n },\n default: ['system', 'database'],\n description: 'Which diagrams to generate (system=component overview, database=ERD, api=endpoint structure, sequence=request flows, deployment=infrastructure)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['requirements'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const requirements = args.requirements as string;\n const repoPath = args.repoPath as string | undefined;\n const existingStack = args.existingStack as string | undefined;\n const constraints = args.constraints as Record<string, unknown> | undefined;\n const focus = (args.focus as string) || 'fullstack';\n const includeDiagrams = (args.includeDiagrams as string[]) || ['system', 'database'];\n const projectRoot = (args.projectRoot as string) || repoPath || process.cwd();\n\n if (!requirements || requirements.trim().length === 0) {\n return errorResult('Requirements are required');\n }\n\n // Auto-discover database schemas if repoPath provided\n let schemaContext = '';\n let discoveredSchemas: SchemaFile[] = [];\n if (repoPath) {\n discoveredSchemas = discoverSchemaFiles(repoPath);\n if (discoveredSchemas.length > 0) {\n schemaContext = formatSchemasForPrompt(discoveredSchemas);\n }\n }\n\n // Build diagram instructions based on what's requested\n const diagramInstructions: string[] = [];\n if (includeDiagrams.includes('system')) {\n diagramInstructions.push(`\n### System Architecture Diagram\nCreate a Mermaid flowchart showing the high-level system components:\n\\`\\`\\`mermaid\nflowchart TB\n subgraph Client\n Web[Web App]\n Mobile[Mobile App]\n end\n subgraph Backend\n API[API Gateway]\n Auth[Auth Service]\n Core[Core Service]\n end\n subgraph Data\n DB[(Database)]\n Cache[(Cache)]\n end\n Web --> API\n Mobile --> API\n API --> Auth\n API --> Core\n Core --> DB\n Core --> Cache\n\\`\\`\\`\n`);\n }\n\n if (includeDiagrams.includes('database')) {\n diagramInstructions.push(`\n### Database Schema (ERD)\nCreate a Mermaid erDiagram showing entity relationships:\n\\`\\`\\`mermaid\nerDiagram\n USER ||--o{ ORDER : places\n USER {\n uuid id PK\n string email UK\n string name\n timestamp created_at\n }\n ORDER ||--|{ ORDER_ITEM : contains\n ORDER {\n uuid id PK\n uuid user_id FK\n decimal total\n string status\n }\n PRODUCT ||--o{ ORDER_ITEM : \"ordered in\"\n ORDER_ITEM {\n uuid id PK\n uuid order_id FK\n uuid product_id FK\n int quantity\n }\n\\`\\`\\`\nGenerate an accurate ERD from the discovered schemas or requirements.\n`);\n }\n\n if (includeDiagrams.includes('api')) {\n diagramInstructions.push(`\n### API Structure Diagram\nCreate a Mermaid flowchart showing API endpoints grouped by resource:\n\\`\\`\\`mermaid\nflowchart LR\n subgraph Auth\n POST_login[POST /auth/login]\n POST_register[POST /auth/register]\n POST_refresh[POST /auth/refresh]\n end\n subgraph Users\n GET_users[GET /users]\n GET_user[GET /users/:id]\n PUT_user[PUT /users/:id]\n end\n\\`\\`\\`\n`);\n }\n\n if (includeDiagrams.includes('sequence')) {\n diagramInstructions.push(`\n### Request Flow Sequence Diagram\nCreate a Mermaid sequence diagram showing a typical request flow:\n\\`\\`\\`mermaid\nsequenceDiagram\n participant C as Client\n participant A as API Gateway\n participant S as Service\n participant D as Database\n\n C->>A: POST /api/orders\n A->>A: Validate JWT\n A->>S: Create Order\n S->>D: INSERT order\n D-->>S: order_id\n S-->>A: Order Created\n A-->>C: 201 Created\n\\`\\`\\`\n`);\n }\n\n if (includeDiagrams.includes('deployment')) {\n diagramInstructions.push(`\n### Deployment Diagram\nCreate a Mermaid flowchart showing infrastructure:\n\\`\\`\\`mermaid\nflowchart TB\n subgraph Cloud[\"Cloud Provider\"]\n subgraph Edge\n CDN[CDN]\n LB[Load Balancer]\n end\n subgraph Compute\n App1[App Instance 1]\n App2[App Instance 2]\n end\n subgraph Data\n Primary[(Primary DB)]\n Replica[(Read Replica)]\n Redis[(Redis Cache)]\n end\n end\n Users --> CDN --> LB\n LB --> App1 & App2\n App1 & App2 --> Primary\n App1 & App2 --> Replica\n App1 & App2 --> Redis\n\\`\\`\\`\n`);\n }\n\n const systemPrompt = `You are a senior solutions architect specializing in modern software systems. Your task is to create a comprehensive technical architecture document with accurate Mermaid diagrams.\n\n${schemaContext ? 'IMPORTANT: Database schemas have been auto-discovered from the codebase. Use these EXACT table/model names and relationships in your diagrams.\\n' : ''}\n\nInclude the following sections:\n1. **Architecture Overview** - High-level system design\n2. **Diagrams** - Generate the requested Mermaid diagrams:\n${diagramInstructions.join('\\n')}\n3. **Components** - Detailed breakdown of each component\n4. **Data Models** - Entity relationships and schemas${schemaContext ? ' (use discovered schemas)' : ''}\n5. **API Design** - Endpoint structure and contracts\n6. **Technology Recommendations** - Stack choices with rationale\n7. **Security Architecture** - Auth, encryption, access control\n8. **Scalability Plan** - How the system grows\n9. **Infrastructure** - Deployment and hosting\n10. **Risks & Trade-offs** - Technical debt and decisions\n\nDIAGRAM GUIDELINES:\n- Use valid Mermaid syntax (flowchart, erDiagram, sequenceDiagram)\n- For ERD: Use discovered table names exactly as they appear in schemas\n- For flowcharts: Use descriptive node names\n- For sequences: Show realistic request/response flows\n- Include cardinality in ERD relationships (||--o{, ||--|{, }o--o{)\n\nFocus Area: ${focus}\n${existingStack ? `Existing Stack: ${existingStack}` : ''}\n${constraints ? `Constraints: ${JSON.stringify(constraints)}` : ''}`;\n\n const userMessage = `Create a technical architecture for the following requirements:\n\n${requirements.length > 10000 ? requirements.substring(0, 10000) + '\\n... [truncated]' : requirements}\n\n${schemaContext ? `\\n---\\n${schemaContext}` : ''}\n\nGenerate a comprehensive architecture document with the requested Mermaid diagrams: ${includeDiagrams.join(', ')}.\n${discoveredSchemas.length > 0 ? `\\nNote: ${discoveredSchemas.length} schema file(s) discovered. Use these for accurate ERD generation.` : ''}`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 8000, // Increased for multiple diagrams\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('generate_architecture');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_architecture',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [focus, ...includeDiagrams],\n tokensUsed: totalTokens,\n });\n\n const schemaNote = discoveredSchemas.length > 0\n ? `\\n\\n---\\n📊 **Schemas discovered:** ${discoveredSchemas.map(s => s.relativePath).join(', ')}`\n : '';\n\n return markdownResult(result.text + schemaNote + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate architecture: ${message}`);\n }\n },\n\n requiredScope: 'tools:generate_architecture',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, extname, relative, resolve } from 'path';\n\n// ============================================================================\n// Environment Variable Discovery\n// ============================================================================\n\ninterface EnvVariable {\n name: string;\n source: string;\n line: number;\n hasDefault: boolean;\n defaultValue?: string;\n}\n\n/**\n * Scan codebase for environment variable usage\n */\nfunction discoverEnvVariables(repoPath: string): EnvVariable[] {\n const envVars: EnvVariable[] = [];\n const seen = new Set<string>();\n const resolvedPath = resolve(repoPath);\n\n if (!existsSync(resolvedPath)) {\n return envVars;\n }\n\n const ignoreDirs = new Set(['node_modules', 'dist', 'build', '.next', 'coverage', '.git', '__pycache__']);\n const maxFileSize = 256 * 1024;\n const maxFiles = 100;\n let filesScanned = 0;\n\n // Patterns to find env variables\n const patterns = [\n /process\\.env\\.(\\w+)/g, // process.env.VAR_NAME\n /process\\.env\\[['\"](\\w+)['\"]\\]/g, // process.env['VAR_NAME']\n /import\\.meta\\.env\\.(\\w+)/g, // import.meta.env.VAR_NAME (Vite)\n /Deno\\.env\\.get\\(['\"](\\w+)['\"]\\)/g, // Deno.env.get('VAR_NAME')\n /os\\.environ\\.get\\(['\"](\\w+)['\"]\\)/g, // Python os.environ.get\n /os\\.getenv\\(['\"](\\w+)['\"]\\)/g, // Python os.getenv\n /env\\(['\"](\\w+)['\"]\\)/g, // Generic env() helper\n ];\n\n // Pattern to detect defaults\n const defaultPatterns = [\n /process\\.env\\.(\\w+)\\s*\\|\\|\\s*['\"]([^'\"]+)['\"]/g, // process.env.VAR || 'default'\n /process\\.env\\.(\\w+)\\s*\\?\\?\\s*['\"]([^'\"]+)['\"]/g, // process.env.VAR ?? 'default'\n /process\\.env\\[['\"](\\w+)['\"]\\]\\s*\\|\\|\\s*['\"]([^'\"]+)['\"]/g,\n ];\n\n function walkDir(dir: string, depth = 0): void {\n if (depth > 8 || filesScanned >= maxFiles) return;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (filesScanned >= maxFiles) break;\n\n const fullPath = join(dir, entry.name);\n const relativePath = relative(resolvedPath, fullPath);\n\n if (entry.isDirectory()) {\n if (!ignoreDirs.has(entry.name) && !entry.name.startsWith('.')) {\n walkDir(fullPath, depth + 1);\n }\n continue;\n }\n\n if (!entry.isFile()) continue;\n\n const ext = extname(entry.name);\n if (!['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.env.example', '.env.local'].includes(ext) &&\n !entry.name.includes('.env')) continue;\n\n try {\n const stat = statSync(fullPath);\n if (stat.size > maxFileSize) continue;\n\n filesScanned++;\n const content = readFileSync(fullPath, 'utf-8');\n const lines = content.split('\\n');\n\n // First pass: find defaults\n const defaults = new Map<string, string>();\n for (const pattern of defaultPatterns) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(content)) !== null) {\n const key = match[1];\n const val = match[2];\n if (key && val) {\n defaults.set(key, val);\n }\n }\n }\n\n // Second pass: find all env vars\n for (const pattern of patterns) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(content)) !== null) {\n const varName = match[1];\n if (!varName || seen.has(varName)) continue;\n seen.add(varName);\n\n // Find line number\n const matchIndex = match.index;\n let lineNum = 1;\n let charCount = 0;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line !== undefined) {\n charCount += line.length + 1;\n }\n if (charCount > matchIndex) {\n lineNum = i + 1;\n break;\n }\n }\n\n envVars.push({\n name: varName,\n source: relativePath,\n line: lineNum,\n hasDefault: defaults.has(varName),\n defaultValue: defaults.get(varName),\n });\n }\n }\n\n // Also parse .env.example files\n if (entry.name.includes('.env')) {\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line || line.startsWith('#')) continue;\n const eqIndex = line.indexOf('=');\n if (eqIndex > 0) {\n const varName = line.substring(0, eqIndex).trim();\n if (seen.has(varName)) continue;\n seen.add(varName);\n envVars.push({\n name: varName,\n source: relativePath,\n line: i + 1,\n hasDefault: eqIndex < line.length - 1,\n defaultValue: line.substring(eqIndex + 1).trim() || undefined,\n });\n }\n }\n }\n } catch {\n // Skip files that can't be read\n }\n }\n } catch {\n // Skip directories that can't be read\n }\n }\n\n walkDir(resolvedPath);\n\n // Sort by name for consistent output\n return envVars.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Format environment variables as .env.example content\n */\nfunction formatEnvExample(envVars: EnvVariable[]): string {\n if (envVars.length === 0) return '';\n\n const lines = [\n '# Environment Variables',\n '# Generated by VasperaPM handoff_package',\n '# Copy this file to .env and fill in your values',\n '',\n ];\n\n // Group by category (inferred from name prefix)\n const categories: Record<string, EnvVariable[]> = {\n 'Database': [],\n 'Authentication': [],\n 'API Keys': [],\n 'Services': [],\n 'Other': [],\n };\n\n for (const v of envVars) {\n const nameLower = v.name.toLowerCase();\n if (nameLower.includes('database') || nameLower.includes('db_') || nameLower.includes('postgres') || nameLower.includes('mysql') || nameLower.includes('mongo') || nameLower.includes('supabase')) {\n categories['Database']!.push(v);\n } else if (nameLower.includes('auth') || nameLower.includes('jwt') || nameLower.includes('secret') || nameLower.includes('session')) {\n categories['Authentication']!.push(v);\n } else if (nameLower.includes('api_key') || nameLower.includes('apikey') || nameLower.includes('_key') || nameLower.includes('anthropic') || nameLower.includes('openai') || nameLower.includes('stripe')) {\n categories['API Keys']!.push(v);\n } else if (nameLower.includes('url') || nameLower.includes('host') || nameLower.includes('port') || nameLower.includes('endpoint')) {\n categories['Services']!.push(v);\n } else {\n categories['Other']!.push(v);\n }\n }\n\n for (const [category, vars] of Object.entries(categories)) {\n if (vars.length === 0) continue;\n lines.push(`# ${category}`);\n for (const v of vars) {\n const value = v.hasDefault && v.defaultValue ? v.defaultValue : '';\n const comment = v.hasDefault ? '' : ' # Required';\n lines.push(`${v.name}=${value}${comment}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * handoff_package tool - Creates complete developer handoff packages\n */\nexport const handoffPackageTool: ToolDefinition = {\n tool: {\n name: 'handoff_package',\n description: `Create a complete developer handoff package from PM artifacts.\n\nTakes PRD, designs, and specs to generate:\n- Implementation guide\n- Acceptance criteria checklist\n- Edge cases and error handling\n- Testing requirements\n- Definition of Done\n\nBest for: Preparing work for engineering sprint planning.`,\n inputSchema: {\n type: 'object',\n properties: {\n prd: {\n type: 'string',\n description: 'Product Requirements Document content',\n },\n designs: {\n type: 'string',\n description: 'Design descriptions or Figma links',\n },\n techSpecs: {\n type: 'string',\n description: 'Technical specifications or architecture docs',\n },\n repoPath: {\n type: 'string',\n description: 'Path to repository for auto-discovery of environment variables and file structure',\n },\n targetTeam: {\n type: 'string',\n enum: ['frontend', 'backend', 'fullstack', 'mobile', 'devops'],\n default: 'fullstack',\n description: 'Target development team',\n },\n sprintDuration: {\n type: 'number',\n default: 2,\n description: 'Sprint duration in weeks',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['prd'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const prd = args.prd as string;\n const designs = args.designs as string | undefined;\n const techSpecs = args.techSpecs as string | undefined;\n const repoPath = args.repoPath as string | undefined;\n const targetTeam = (args.targetTeam as string) || 'fullstack';\n const sprintDuration = (args.sprintDuration as number) || 2;\n const projectRoot = (args.projectRoot as string) || repoPath || process.cwd();\n\n if (!prd || prd.trim().length === 0) {\n return errorResult('PRD content is required');\n }\n\n // Discover environment variables if repoPath is provided\n let envSection = '';\n let envExample = '';\n if (repoPath) {\n const envVars = discoverEnvVariables(repoPath);\n if (envVars.length > 0) {\n envExample = formatEnvExample(envVars);\n envSection = `\n\n## 10. Environment Setup\n\n### Required Environment Variables\nThe following environment variables were discovered in the codebase:\n\n| Variable | Source | Required | Default |\n|----------|--------|----------|---------|\n${envVars.map(v => `| \\`${v.name}\\` | ${v.source}:${v.line} | ${v.hasDefault ? 'No' : 'Yes'} | ${v.defaultValue || '-'} |`).join('\\n')}\n\n### .env.example\nCopy the following to \\`.env\\` and fill in your values:\n\n\\`\\`\\`bash\n${envExample}\n\\`\\`\\`\n\n### Quick Start Commands\n\\`\\`\\`bash\n# Clone and setup\ngit clone <repo-url>\ncd <project-name>\ncp .env.example .env\n# Edit .env with your values\n\n# Install dependencies\npnpm install # or npm install\n\n# Start development\npnpm dev # or npm run dev\n\\`\\`\\`\n`;\n }\n }\n\n const systemPrompt = `You are an expert technical program manager who creates flawless developer handoff packages for enterprise development teams.\n\nCreate a handoff package with these sections:\n\n1. **Summary** - What we're building and why (2-3 paragraphs)\n\n2. **Implementation Guide**\n - Step-by-step implementation order with NUMBERED PHASES\n - Dependencies between components\n - Critical path items marked clearly\n - **FILE CREATION ORDER**: List files in the exact order they should be created to avoid circular dependencies\n\n3. **Code Examples** - CRITICAL REQUIREMENTS:\n - Every code example MUST include complete import statements\n - Show the full file path where code should go\n - Include TypeScript types\n - Example format:\n \\`\\`\\`typescript\n // File: src/services/auth.ts\n import { createClient } from '@supabase/supabase-js';\n import type { User, Session } from '../types/auth.js';\n import { config } from '../config/index.js';\n\n export class AuthService {\n // ... implementation\n }\n \\`\\`\\`\n\n4. **Acceptance Criteria** - Testable requirements for each feature (Given/When/Then format)\n\n5. **Edge Cases** - All the \"what if\" scenarios with handling strategy\n\n6. **Error Handling** - Specific error types and recovery strategies\n\n7. **Testing Requirements**\n - Unit test file locations and patterns\n - Integration test scenarios\n - E2E test flows with Playwright/Cypress examples\n\n8. **Definition of Done** - Checkbox checklist for completion\n\n9. **Questions for PM** - Clarifications needed before starting\n\n10. **Risks** - Implementation risks with severity and mitigation\n\nCRITICAL GUIDELINES:\n- Be extremely specific - no ambiguity\n- ALL code examples MUST have complete imports (no \"import { ... }\" shortcuts)\n- Specify exact file paths for all code\n- Include TypeScript types in examples\n- List files in creation order (dependencies first)\n- Consider accessibility requirements\n- Note performance expectations\n\nTarget Team: ${targetTeam}\nSprint Duration: ${sprintDuration} weeks`;\n\n let userMessage = `Create a developer handoff package from:\n\n## PRD\n${prd.length > 10000 ? prd.substring(0, 10000) + '\\n... [truncated]' : prd}`;\n\n if (designs) {\n userMessage += `\\n\\n## Design Specs\\n${designs}`;\n }\n\n if (techSpecs) {\n userMessage += `\\n\\n## Technical Specs\\n${techSpecs}`;\n }\n\n userMessage += '\\n\\nCreate a comprehensive handoff package with complete code examples including all imports.';\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Combine AI-generated content with discovered environment section\n const fullContent = result.text + envSection;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('handoff_package');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'handoff_package',\n category: defaults.category,\n filename: defaults.filename,\n content: fullContent,\n format: 'md',\n inputs: [targetTeam],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(fullContent + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to create handoff package: ${message}`);\n }\n },\n\n requiredScope: 'tools:handoff_package',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * synthesize_requirements tool - Extracts and consolidates requirements from various sources\n */\nexport const synthesizeRequirementsTool: ToolDefinition = {\n tool: {\n name: 'synthesize_requirements',\n description: `Extract and synthesize requirements from various input sources with CONFLICT DETECTION.\n\nTakes meeting notes, emails, slack threads, user feedback, or any unstructured input and produces:\n- Functional requirements (what the system must do)\n- Non-functional requirements (performance, security, scalability)\n- User stories in standard format\n- Acceptance criteria for each requirement\n- Requirement dependencies and priorities\n- **CONFLICT DETECTION**: Flags when sources disagree on requirements\n- **CONFIDENCE SCORES**: How certain we are about each requirement (100%=all agree, 25%=ambiguous)\n- **SOURCE AGREEMENT MATRIX**: Visual comparison of which sources agree/disagree\n\nBest for: Converting messy stakeholder input into structured requirements AND identifying where stakeholders disagree.`,\n inputSchema: {\n type: 'object',\n properties: {\n sources: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n type: {\n type: 'string',\n enum: ['meeting_notes', 'email', 'slack', 'feedback', 'interview', 'survey', 'other'],\n },\n stakeholder: { type: 'string' },\n date: { type: 'string' },\n },\n required: ['content'],\n },\n description: 'Array of source documents to analyze',\n },\n context: {\n type: 'string',\n description: 'Product or feature context to help interpretation',\n },\n outputFormat: {\n type: 'string',\n enum: ['user_stories', 'requirements_doc', 'both'],\n default: 'both',\n description: 'Output format preference',\n },\n priorityFramework: {\n type: 'string',\n enum: ['moscow', 'rice', 'kano', 'value_effort'],\n default: 'moscow',\n description: 'Prioritization framework to use',\n },\n conflictSensitivity: {\n type: 'string',\n enum: ['strict', 'moderate', 'lenient'],\n default: 'moderate',\n description: 'How aggressively to flag potential conflicts (strict=flag everything, lenient=only critical)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['sources'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const sources = args.sources as Array<{\n content: string;\n type?: string;\n stakeholder?: string;\n date?: string;\n }>;\n const context = args.context as string | undefined;\n const outputFormat = (args.outputFormat as string) || 'both';\n const priorityFramework = (args.priorityFramework as string) || 'moscow';\n const conflictSensitivity = (args.conflictSensitivity as string) || 'moderate';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!sources || sources.length === 0) {\n return errorResult('At least one source document is required');\n }\n\n const conflictInstructions: Record<string, string> = {\n strict: 'Flag ALL potential conflicts, even minor wording differences. Be extremely thorough.',\n moderate: 'Flag significant conflicts that could affect implementation. Balance thoroughness with relevance.',\n lenient: 'Only flag critical conflicts that are mutually exclusive or would break the product.',\n };\n\n const priorityDescriptions: Record<string, string> = {\n moscow: 'MoSCoW (Must have, Should have, Could have, Won\\'t have)',\n rice: 'RICE (Reach, Impact, Confidence, Effort)',\n kano: 'Kano Model (Basic, Performance, Excitement)',\n value_effort: 'Value/Effort Matrix (Quick wins, Big bets, Fill-ins, Time sinks)',\n };\n\n const systemPrompt = `You are a senior business analyst expert at extracting clear requirements from ambiguous stakeholder input.\n\nYour task is to analyze the provided sources and produce structured requirements with CONFLICT DETECTION.\n\nOutput Sections:\n1. **Executive Summary** - Key themes and scope overview\n\n2. **Conflicts Detected** - CRITICAL: Cross-reference ALL sources and flag disagreements\n For each conflict found, output a table row:\n | Requirement Area | Source 1 Says | Source 2 Says | Severity | Resolution Needed |\n\n Severity levels:\n - 🔴 CRITICAL: Mutually exclusive requirements, cannot build both\n - 🟠 HIGH: Significant disagreement on approach or priority\n - 🟡 MEDIUM: Different details that need clarification\n - 🟢 LOW: Minor wording differences, easily reconciled\n\n3. **Functional Requirements** - What the system must do\n - ID, Description, Priority, Source reference\n - **Confidence Score** (0-100%): How certain are we about this requirement?\n - 100%: Multiple sources agree explicitly\n - 75%: One source explicit, others don't contradict\n - 50%: Inferred from context, no explicit statement\n - 25%: Single ambiguous mention\n\n4. **Non-Functional Requirements** - Quality attributes\n - Performance, Security, Scalability, Accessibility, etc.\n - Include confidence scores\n\n5. **User Stories** - In \"As a [role], I want [feature], so that [benefit]\" format\n - Include acceptance criteria for each\n - Include confidence scores\n\n6. **Requirement Dependencies** - Which requirements depend on others\n\n7. **Source Agreement Matrix** - Show which sources agree/disagree on each major topic\n | Topic | Source 1 | Source 2 | Source 3 | Agreement |\n Use ✓ (agrees), ✗ (disagrees), ? (no mention), ⚠ (partial)\n\n8. **Priority Matrix** - Using ${priorityDescriptions[priorityFramework]}\n\n9. **Gaps & Ambiguities** - What's unclear or missing\n\n10. **Recommended Clarifications** - Questions for stakeholders to resolve conflicts\n\nCONFLICT DETECTION RULES:\n- Compare EVERY source against EVERY other source\n- Look for: different priorities, contradicting features, timeline disagreements\n- Look for: scope differences, budget/resource conflicts, technical approach conflicts\n- Flag when one source says \"must have X\" and another says \"should not have X\"\n- Flag when sources give different numbers (quotas, limits, timelines)\n- Flag when sources describe the same feature differently\n\nCONFLICT SENSITIVITY: ${conflictInstructions[conflictSensitivity]}\n\n${context ? `Product Context: ${context}` : ''}`;\n\n // Format sources for the prompt\n const formattedSources = sources\n .map((source, i) => {\n const meta = [\n source.type ? `Type: ${source.type}` : null,\n source.stakeholder ? `Stakeholder: ${source.stakeholder}` : null,\n source.date ? `Date: ${source.date}` : null,\n ]\n .filter(Boolean)\n .join(' | ');\n\n return `### Source ${i + 1}${meta ? ` (${meta})` : ''}\\n${source.content}`;\n })\n .join('\\n\\n---\\n\\n');\n\n const userMessage = `Analyze these sources and extract structured requirements:\n\n${formattedSources.length > 15000 ? formattedSources.substring(0, 15000) + '\\n... [truncated]' : formattedSources}\n\nOutput format preference: ${outputFormat}\nPrioritization framework: ${priorityFramework}\n\nExtract all requirements with proper structure and traceability.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('synthesize_requirements');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'synthesize_requirements',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: sources.map((s) => s.type || 'unknown'),\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to synthesize requirements: ${message}`);\n }\n },\n\n requiredScope: 'tools:synthesize_requirements',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * review_prd tool - Comprehensive PRD review and critique\n */\nexport const reviewPrdTool: ToolDefinition = {\n tool: {\n name: 'review_prd',\n description: `Review and critique a Product Requirements Document.\n\nAnalyzes a PRD against best practices and provides:\n- Completeness assessment\n- Clarity and ambiguity analysis\n- Gap identification\n- Risk assessment\n- Improvement suggestions\n- Readiness score\n\nBest for: Quality assurance before engineering handoff.`,\n inputSchema: {\n type: 'object',\n properties: {\n prd: {\n type: 'string',\n description: 'The PRD content to review',\n },\n reviewFocus: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'completeness',\n 'clarity',\n 'technical_feasibility',\n 'user_value',\n 'metrics',\n 'edge_cases',\n 'security',\n 'accessibility',\n ],\n },\n default: ['completeness', 'clarity', 'technical_feasibility'],\n description: 'Areas to focus the review on',\n },\n targetAudience: {\n type: 'string',\n enum: ['engineering', 'stakeholders', 'both'],\n default: 'engineering',\n description: 'Primary audience for the PRD',\n },\n strictness: {\n type: 'string',\n enum: ['lenient', 'standard', 'strict'],\n default: 'standard',\n description: 'How strict the review should be',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['prd'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const prd = args.prd as string;\n const reviewFocus = (args.reviewFocus as string[]) || [\n 'completeness',\n 'clarity',\n 'technical_feasibility',\n ];\n const targetAudience = (args.targetAudience as string) || 'engineering';\n const strictness = (args.strictness as string) || 'standard';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!prd || prd.trim().length === 0) {\n return errorResult('PRD content is required for review');\n }\n\n const strictnessGuide: Record<string, string> = {\n lenient: 'Be constructive and focus on major issues only. Assume good intent and fill in reasonable gaps.',\n standard: 'Balance thoroughness with practicality. Flag important issues but don\\'t nitpick.',\n strict: 'Apply rigorous standards. Flag all issues, ambiguities, and potential problems. This PRD should be bulletproof.',\n };\n\n const systemPrompt = `You are a senior product management coach who has reviewed thousands of PRDs. Your job is to provide actionable, constructive feedback.\n\nReview the PRD with these priorities:\n${reviewFocus.map((f) => `- ${f}`).join('\\n')}\n\nProvide a structured review with:\n\n1. **Overall Assessment**\n - Readiness Score (1-10)\n - Summary judgment (Ready / Needs Work / Major Revision Needed)\n\n2. **Strengths**\n - What's done well\n\n3. **Completeness Analysis**\n - Required sections present/missing\n - Depth of coverage\n\n4. **Clarity Issues**\n - Ambiguous requirements (quote specific text)\n - Missing definitions\n - Unclear scope boundaries\n\n5. **Technical Feasibility Concerns**\n - Potentially challenging requirements\n - Missing technical considerations\n - Architecture implications not addressed\n\n6. **Gap Analysis**\n - Missing use cases\n - Unaddressed edge cases\n - Missing acceptance criteria\n\n7. **Risk Assessment**\n - Implementation risks\n - Timeline risks\n - Dependency risks\n\n8. **Specific Recommendations**\n - Prioritized list of improvements\n - Suggested rewrites for unclear sections\n\n9. **Questions for PM**\n - Clarifications needed before engineering can start\n\nReview Strictness: ${strictnessGuide[strictness]}\nTarget Audience: ${targetAudience}`;\n\n const userMessage = `Review this PRD and provide comprehensive feedback:\n\n${prd.length > 15000 ? prd.substring(0, 15000) + '\\n... [truncated]' : prd}\n\nProvide a thorough review with actionable feedback.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('review_prd');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'review_prd',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: ['prd'],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to review PRD: ${message}`);\n }\n },\n\n requiredScope: 'tools:review_prd',\n};\n","/**\n * Generic CSV Generation Utilities\n *\n * Provides low-level CSV generation functions that can be used\n * across different tools for platform-agnostic CSV output.\n */\n\n/**\n * Options for CSV generation\n */\nexport interface CSVOptions {\n /** Delimiter between values (default: ',') */\n delimiter?: string;\n /** Line ending (default: '\\n') */\n lineEnding?: string;\n /** Whether to include header row (default: true) */\n includeHeader?: boolean;\n}\n\n/**\n * Escape a value for CSV output.\n * Wraps in quotes and escapes internal quotes by doubling them.\n *\n * @example\n * escapeCSV('Hello, World') // '\"Hello, World\"'\n * escapeCSV('Say \"Hello\"') // '\"Say \"\"Hello\"\"\"'\n */\nexport function escapeCSV(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n const stringValue = String(value);\n\n // Always wrap in quotes for consistency and to handle special characters\n return `\"${stringValue.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Convert a value to CSV format without quotes (for simple values).\n * Only use for values known to be safe (no commas, quotes, or newlines).\n */\nexport function toCSVValue(value: string | number | boolean | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n return String(value);\n}\n\n/**\n * Generate a CSV row from an array of values\n *\n * @param values - Array of cell values\n * @param options - CSV options\n * @returns CSV row string\n */\nexport function generateCSVRow(\n values: (string | number | boolean | null | undefined)[],\n options: CSVOptions = {}\n): string {\n const delimiter = options.delimiter ?? ',';\n return values.map((v) => escapeCSV(v)).join(delimiter);\n}\n\n/**\n * Generate a CSV row from an array of values without escaping.\n * Use when values are already formatted or known to be safe.\n */\nexport function generateRawCSVRow(\n values: (string | number | boolean | null | undefined)[],\n options: CSVOptions = {}\n): string {\n const delimiter = options.delimiter ?? ',';\n return values.map((v) => toCSVValue(v)).join(delimiter);\n}\n\n/**\n * Generate a complete CSV string from headers and rows\n *\n * @param headers - Column headers\n * @param rows - Array of row arrays\n * @param options - CSV options\n * @returns Complete CSV string\n */\nexport function generateCSV(\n headers: string[],\n rows: (string | number | boolean | null | undefined)[][],\n options: CSVOptions = {}\n): string {\n const lineEnding = options.lineEnding ?? '\\n';\n const includeHeader = options.includeHeader ?? true;\n\n const lines: string[] = [];\n\n if (includeHeader) {\n lines.push(headers.join(options.delimiter ?? ','));\n }\n\n for (const row of rows) {\n lines.push(generateCSVRow(row, options));\n }\n\n return lines.join(lineEnding);\n}\n\n/**\n * Generate CSV from an array of objects using specified field mapping\n *\n * @param items - Array of objects to convert\n * @param fieldMap - Map of header names to object accessor functions\n * @param options - CSV options\n * @returns Complete CSV string\n *\n * @example\n * const items = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];\n * generateCSVFromObjects(items, {\n * 'Name': item => item.name,\n * 'Age': item => item.age,\n * });\n * // \"Name,Age\\n\"Alice\",30\\n\"Bob\",25\"\n */\nexport function generateCSVFromObjects<T>(\n items: T[],\n fieldMap: Record<string, (item: T) => string | number | boolean | null | undefined>,\n options: CSVOptions = {}\n): string {\n const headers = Object.keys(fieldMap);\n const rows = items.map((item) => headers.map((header) => fieldMap[header](item)));\n\n return generateCSV(headers, rows, options);\n}\n\n/**\n * Parse a CSV string into rows of strings\n * Note: This is a basic parser and may not handle all edge cases.\n * For production use with untrusted input, consider a dedicated CSV library.\n *\n * @param csv - CSV string to parse\n * @param options - CSV options\n * @returns Array of row arrays\n */\nexport function parseCSV(csv: string, options: CSVOptions = {}): string[][] {\n const delimiter = options.delimiter ?? ',';\n const lines = csv.split(/\\r?\\n/).filter((line) => line.trim());\n const rows: string[][] = [];\n\n for (const line of lines) {\n const row: string[] = [];\n let current = '';\n let inQuotes = false;\n let i = 0;\n\n while (i < line.length) {\n const char = line[i];\n\n if (inQuotes) {\n if (char === '\"') {\n if (line[i + 1] === '\"') {\n // Escaped quote\n current += '\"';\n i += 2;\n } else {\n // End of quoted field\n inQuotes = false;\n i++;\n }\n } else {\n current += char;\n i++;\n }\n } else {\n if (char === '\"') {\n inQuotes = true;\n i++;\n } else if (char === delimiter) {\n row.push(current);\n current = '';\n i++;\n } else {\n current += char;\n i++;\n }\n }\n }\n\n row.push(current);\n rows.push(row);\n }\n\n return rows;\n}\n","/**\n * Shared Utilities\n *\n * Common utility functions used across the MCP server.\n */\n\n// CSV generation utilities\nexport {\n escapeCSV,\n toCSVValue,\n generateCSVRow,\n generateRawCSVRow,\n generateCSV,\n generateCSVFromObjects,\n parseCSV,\n type CSVOptions,\n} from './csv-generator.js';\n","/**\n * CSV Formatter\n *\n * Generates platform-specific CSV formats for direct import.\n * Uses generic CSV utilities from utils/csv-generator.\n */\n\nimport type { TrackerItem } from '@vaspera/shared';\nimport type { AdoProcess } from '../types.js';\nimport { generateCSVFromObjects } from '../../../utils/index.js';\n\n/**\n * ADO work item type mappings per process template\n */\nconst ADO_TYPE_MAPS: Record<AdoProcess, Record<string, string>> = {\n basic: {\n epic: 'Epic',\n feature: 'Issue',\n story: 'Issue',\n issue: 'Issue',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Task',\n },\n agile: {\n epic: 'Epic',\n feature: 'Feature',\n story: 'User Story',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Task',\n },\n scrum: {\n epic: 'Epic',\n feature: 'Feature',\n story: 'Product Backlog Item',\n pbi: 'Product Backlog Item',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Task',\n },\n cmmi: {\n epic: 'Epic',\n feature: 'Feature',\n story: 'Requirement',\n requirement: 'Requirement',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Task',\n },\n};\n\n/**\n * Default work item type per ADO process\n */\nconst ADO_DEFAULT_TYPES: Record<AdoProcess, string> = {\n basic: 'Issue',\n agile: 'User Story',\n scrum: 'Product Backlog Item',\n cmmi: 'Requirement',\n};\n\n/**\n * Jira type mapping\n */\nconst JIRA_TYPE_MAP: Record<string, string> = {\n epic: 'Epic',\n feature: 'Story',\n story: 'Story',\n task: 'Task',\n bug: 'Bug',\n subtask: 'Sub-task',\n};\n\n/**\n * Jira priority mapping\n */\nconst JIRA_PRIORITY_MAP: Record<string, string> = {\n critical: 'Highest',\n high: 'High',\n medium: 'Medium',\n low: 'Low',\n};\n\n/**\n * ADO priority mapping (numeric)\n */\nconst ADO_PRIORITY_MAP: Record<string, number> = {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n};\n\n/**\n * Build description with acceptance criteria for Jira\n */\nfunction buildJiraDescription(item: TrackerItem): string {\n let description = item.description;\n if (item.acceptanceCriteria.length > 0) {\n description += '\\n\\nAcceptance Criteria:\\n' + item.acceptanceCriteria.map((c) => `- ${c}`).join('\\n');\n }\n return description;\n}\n\n/**\n * Generate Jira CSV format\n */\nfunction generateJiraCSV(items: TrackerItem[]): string {\n return generateCSVFromObjects(items, {\n Summary: (item) => item.title,\n 'Issue Type': (item) => JIRA_TYPE_MAP[item.type] || 'Story',\n Priority: (item) => JIRA_PRIORITY_MAP[item.priority] || 'Medium',\n Description: (item) => buildJiraDescription(item),\n Labels: (item) => item.labels.join(','),\n 'Story Points': (item) => item.estimate?.value?.toString() || '',\n Parent: (item) => item.parentId || '',\n });\n}\n\n/**\n * Generate ADO CSV format\n */\nfunction generateAdoCSV(items: TrackerItem[], adoProcess: AdoProcess = 'agile'): string {\n const typeMap = ADO_TYPE_MAPS[adoProcess];\n const defaultType = ADO_DEFAULT_TYPES[adoProcess];\n\n return generateCSVFromObjects(items, {\n 'Work Item Type': (item) => typeMap[item.type] || defaultType,\n Title: (item) => item.title,\n Priority: (item) => ADO_PRIORITY_MAP[item.priority]?.toString() || '3',\n Description: (item) => item.description,\n 'Acceptance Criteria': (item) => item.acceptanceCriteria.map((c) => `- ${c}`).join('\\n'),\n 'Story Points': (item) => item.estimate?.value?.toString() || '',\n Tags: (item) => item.labels.join('; '),\n 'Parent ID': (item) => item.parentId || '',\n });\n}\n\n/**\n * Generate generic CSV format\n */\nfunction generateGenericCSV(items: TrackerItem[]): string {\n return generateCSVFromObjects(items, {\n ID: (item) => item.id,\n Type: (item) => item.type,\n Title: (item) => item.title,\n Description: (item) => item.description,\n Priority: (item) => item.priority,\n Labels: (item) => item.labels.join(','),\n Estimate: (item) => (item.estimate ? `${item.estimate.value} ${item.estimate.unit}` : ''),\n Parent: (item) => item.parentId || '',\n });\n}\n\n/**\n * Generate CSV format for platform import\n *\n * @param items - Tracker items to format\n * @param platform - Target platform (jira, ado, linear, github)\n * @param adoProcess - ADO process template (for ADO only)\n */\nexport function generateCSV(items: TrackerItem[], platform: string, adoProcess?: AdoProcess): string {\n switch (platform) {\n case 'jira':\n return generateJiraCSV(items);\n case 'ado':\n return generateAdoCSV(items, adoProcess);\n default:\n return generateGenericCSV(items);\n }\n}\n","/**\n * Markdown Formatter\n *\n * Generates human-readable markdown preview with hierarchy visualization\n */\n\nimport type { TrackerItem } from '@vaspera/shared';\n\n/**\n * Priority to emoji mapping\n */\nconst PRIORITY_ICONS: Record<string, string> = {\n critical: '\\u{1F534}', // Red circle\n high: '\\u{1F7E0}', // Orange circle\n medium: '\\u{1F7E1}', // Yellow circle\n low: '\\u{1F7E2}', // Green circle\n};\n\n/**\n * Generate summary table by item type\n */\nfunction generateSummaryTable(items: TrackerItem[]): string {\n const byType = items.reduce(\n (acc, item) => {\n acc[item.type] = (acc[item.type] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>\n );\n\n const lines: string[] = [];\n lines.push('## Summary');\n lines.push('| Type | Count |');\n lines.push('|------|-------|');\n\n for (const [type, count] of Object.entries(byType)) {\n lines.push(`| ${type} | ${count} |`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate hierarchy tree view\n */\nfunction generateHierarchyView(items: TrackerItem[]): string {\n const lines: string[] = [];\n lines.push('## Hierarchy');\n lines.push('```');\n\n // Build parent-child relationships\n const itemMap = new Map(items.map((i) => [i.id, i]));\n const roots = items.filter((i) => !i.parentId || !itemMap.has(i.parentId));\n const children = new Map<string, TrackerItem[]>();\n\n for (const item of items) {\n if (item.parentId) {\n const existing = children.get(item.parentId) || [];\n existing.push(item);\n children.set(item.parentId, existing);\n }\n }\n\n function printTree(item: TrackerItem, indent: string, isLast: boolean): void {\n const prefix = isLast ? '\\u2514\\u2500\\u2500 ' : '\\u251C\\u2500\\u2500 ';\n const priorityIcon = PRIORITY_ICONS[item.priority] || PRIORITY_ICONS.medium;\n lines.push(`${indent}${prefix}[${item.type.toUpperCase()}] ${priorityIcon} ${item.title} (${item.id})`);\n\n const itemChildren = children.get(item.id) || [];\n for (let i = 0; i < itemChildren.length; i++) {\n const childIndent = indent + (isLast ? ' ' : '\\u2502 ');\n printTree(itemChildren[i], childIndent, i === itemChildren.length - 1);\n }\n }\n\n for (let i = 0; i < roots.length; i++) {\n printTree(roots[i], '', i === roots.length - 1);\n }\n\n lines.push('```');\n return lines.join('\\n');\n}\n\n/**\n * Generate items detail table\n */\nfunction generateItemsTable(items: TrackerItem[]): string {\n const lines: string[] = [];\n lines.push('## Items Detail');\n lines.push('');\n lines.push('| ID | Type | Title | Priority | Est. |');\n lines.push('|----|------|-------|----------|------|');\n\n for (const item of items) {\n const estimate = item.estimate\n ? `${item.estimate.value}${item.estimate.unit === 'points' ? 'pt' : item.estimate.unit === 'hours' ? 'h' : 'd'}`\n : '-';\n\n const truncatedTitle = item.title.length > 40 ? item.title.substring(0, 40) + '...' : item.title;\n\n lines.push(`| ${item.id} | ${item.type} | ${truncatedTitle} | ${item.priority} | ${estimate} |`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate acceptance criteria section\n */\nfunction generateAcceptanceCriteriaSection(items: TrackerItem[], limit = 10): string {\n const withAC = items.filter((i) => i.acceptanceCriteria.length > 0);\n if (withAC.length === 0) return '';\n\n const lines: string[] = [];\n lines.push('## Acceptance Criteria');\n lines.push('');\n\n for (const item of withAC.slice(0, limit)) {\n lines.push(`### ${item.id}: ${item.title}`);\n for (const ac of item.acceptanceCriteria) {\n lines.push(`- [ ] ${ac}`);\n }\n lines.push('');\n }\n\n if (withAC.length > limit) {\n lines.push(`*... and ${withAC.length - limit} more items with acceptance criteria*`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate human-readable markdown preview with hierarchy visualization\n *\n * @param items - Tracker items to format\n * @param platform - Target platform name\n * @param projectKey - Project key/identifier\n */\nexport function generateMarkdownPreview(items: TrackerItem[], platform: string, projectKey: string): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${platform.toUpperCase()} Import Preview`);\n lines.push(`**Project:** ${projectKey}`);\n lines.push(`**Total Items:** ${items.length}`);\n lines.push(`**Generated:** ${new Date().toISOString()}`);\n lines.push('');\n\n // Summary\n lines.push(generateSummaryTable(items));\n lines.push('');\n\n // Hierarchy\n lines.push(generateHierarchyView(items));\n lines.push('');\n\n // Items detail\n lines.push(generateItemsTable(items));\n lines.push('');\n\n // Acceptance criteria\n const acSection = generateAcceptanceCriteriaSection(items);\n if (acSection) {\n lines.push(acSection);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Import Instructions Generator\n *\n * Generates platform-specific import instructions with CLI examples\n */\n\n/**\n * Generate Jira import instructions\n */\nfunction getJiraInstructions(projectKey: string, itemCount: number): string {\n return `\n## Jira Import Instructions\n\n### Quick Import (CSV) - Recommended\n\n1. Save the CSV content above as \\`${projectKey}_import.csv\\`\n2. Go to **Jira \\u2192 Project Settings \\u2192 External System Import**\n3. Select \"CSV\" and upload the file\n4. Map columns:\n - Summary \\u2192 Summary\n - Issue Type \\u2192 Issue Type\n - Priority \\u2192 Priority\n - Description \\u2192 Description\n - Labels \\u2192 Labels\n - Story Points \\u2192 Story Points (custom field)\n\n### API Import (Automated)\n\n\\`\\`\\`bash\n# Install jira-cli\nnpm install -g jira-cli\n\n# Configure (one-time)\njira-cli configure \\\\\n --host https://YOUR_DOMAIN.atlassian.net \\\\\n --email YOUR_EMAIL \\\\\n --token YOUR_API_TOKEN\n\n# Create issues from JSON file\ncat export.json | jq -c '.issues[]' | while read issue; do\n jira-cli create \\\\\n --project ${projectKey} \\\\\n --type \"$(echo $issue | jq -r '.fields.issuetype.name')\" \\\\\n --summary \"$(echo $issue | jq -r '.fields.summary')\" \\\\\n --description \"$(echo $issue | jq -r '.fields.description')\"\ndone\n\\`\\`\\`\n\n### Post-Import Checklist\n\n- [ ] ${itemCount} items created\n- [ ] Epic links established (Edit each Story \\u2192 Epic Link field)\n- [ ] Story points populated\n- [ ] Labels applied correctly\n`;\n}\n\n/**\n * Generate ADO import instructions\n */\nfunction getAdoInstructions(projectKey: string, itemCount: number): string {\n return `\n## Azure DevOps Import Instructions\n\n### Quick Import (Excel) - Recommended\n\n1. Go to **Azure DevOps \\u2192 Boards \\u2192 Work Items**\n2. Click **Import Work Items** (top right)\n3. Download the Excel template\n4. Copy data from the CSV above into the template\n5. Upload and map columns\n\n### CLI Import\n\n\\`\\`\\`bash\n# Install Azure CLI + DevOps extension\naz extension add --name azure-devops\n\n# Configure defaults\naz devops configure --defaults \\\\\n organization=https://dev.azure.com/YOUR_ORG \\\\\n project=${projectKey}\n\n# Create work items\naz boards work-item create \\\\\n --type \"User Story\" \\\\\n --title \"TITLE\" \\\\\n --description \"DESC\" \\\\\n --fields \"Microsoft.VSTS.Common.Priority=2\"\n\\`\\`\\`\n\n### Post-Import Checklist\n\n- [ ] ${itemCount} work items created\n- [ ] Parent-child links established (Boards \\u2192 Links \\u2192 Add Link \\u2192 Parent)\n- [ ] Story points populated\n- [ ] Tags applied correctly\n`;\n}\n\n/**\n * Generate Linear import instructions\n */\nfunction getLinearInstructions(_projectKey: string, itemCount: number): string {\n return `\n## Linear Import Instructions\n\n### GraphQL API Import\n\n\\`\\`\\`bash\ncurl -X POST https://api.linear.app/graphql \\\\\n -H \"Authorization: YOUR_API_KEY\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -d '{\n \"query\": \"mutation { issueCreate(input: {teamId: \\\\\"YOUR_TEAM_ID\\\\\", title: \\\\\"Title\\\\\", description: \\\\\"Desc\\\\\"}) { success } }\"\n }'\n\\`\\`\\`\n\n### Post-Import Checklist\n\n- [ ] ${itemCount} issues created\n- [ ] Project/cycle assigned\n- [ ] Priority set\n`;\n}\n\n/**\n * Generate GitHub import instructions\n */\nfunction getGitHubInstructions(_projectKey: string, itemCount: number): string {\n return `\n## GitHub Issues Import Instructions\n\n### GitHub CLI (Recommended)\n\n\\`\\`\\`bash\n# Install GitHub CLI\nbrew install gh # macOS\n\n# Create issues\ngh issue create \\\\\n --title \"Issue Title\" \\\\\n --body \"Description\" \\\\\n --label \"label1,label2\"\n\\`\\`\\`\n\n### Bulk Import Script\n\n\\`\\`\\`bash\ncat issues.json | jq -c '.issues[]' | while read issue; do\n gh issue create \\\\\n --title \"$(echo $issue | jq -r '.title')\" \\\\\n --body \"$(echo $issue | jq -r '.body')\" \\\\\n --label \"$(echo $issue | jq -r '.labels | join(\",\")')\"\ndone\n\\`\\`\\`\n\n### Post-Import Checklist\n\n- [ ] ${itemCount} issues created\n- [ ] Labels created and applied\n- [ ] Milestones set (if using)\n`;\n}\n\n/**\n * Generate platform-specific import instructions\n *\n * @param platform - Target platform\n * @param projectKey - Project key/identifier\n * @param itemCount - Number of items being imported\n */\nexport function getImportInstructions(platform: string, projectKey: string, itemCount: number): string {\n switch (platform) {\n case 'jira':\n return getJiraInstructions(projectKey, itemCount);\n case 'ado':\n return getAdoInstructions(projectKey, itemCount);\n case 'linear':\n return getLinearInstructions(projectKey, itemCount);\n case 'github':\n return getGitHubInstructions(projectKey, itemCount);\n default:\n return getJiraInstructions(projectKey, itemCount);\n }\n}\n","/**\n * Formatters index\n */\n\nexport { generateCSV } from './csv-formatter.js';\nexport { generateMarkdownPreview } from './markdown-formatter.js';\nexport { getImportInstructions } from './import-instructions.js';\n","/**\n * Platform Configuration\n *\n * Configuration for different project management platforms and ADO process templates\n */\n\nimport type { AdoProcess, AdoProcessConfig, PlatformConfig } from '../types.js';\n\n/**\n * ADO process-specific configurations\n */\nexport const ADO_PROCESS_CONFIG: Record<AdoProcess, AdoProcessConfig> = {\n basic: {\n hierarchy: 'Epic > Issue > Task',\n types: 'epic|issue|task|bug',\n middleType: 'Issue',\n storyType: 'issue',\n },\n agile: {\n hierarchy: 'Epic > Feature > User Story > Task',\n types: 'epic|feature|story|task|bug',\n middleType: 'Feature',\n storyType: 'story',\n },\n scrum: {\n hierarchy: 'Epic > Feature > Product Backlog Item > Task',\n types: 'epic|feature|pbi|task|bug',\n middleType: 'Feature',\n storyType: 'pbi',\n },\n cmmi: {\n hierarchy: 'Epic > Feature > Requirement > Task',\n types: 'epic|feature|requirement|task|bug',\n middleType: 'Feature',\n storyType: 'requirement',\n },\n};\n\n/**\n * Get ADO process config with fallback to agile\n */\nexport function getAdoProcessConfig(process: string): AdoProcessConfig {\n return ADO_PROCESS_CONFIG[process as AdoProcess] || ADO_PROCESS_CONFIG.agile;\n}\n\n/**\n * Platform hierarchy configurations\n */\nexport function getPlatformConfig(platform: string, adoProcess?: string): PlatformConfig {\n const adoConfig = adoProcess ? getAdoProcessConfig(adoProcess) : ADO_PROCESS_CONFIG.agile;\n\n const configs: Record<string, PlatformConfig> = {\n jira: {\n hierarchy: 'Epic > Story > Task > Subtask',\n estimateFormat: 'Story points (fibonacci: 1, 2, 3, 5, 8, 13) or time (1h, 2h, 4h, 1d, 2d)',\n },\n ado: {\n hierarchy: adoConfig.hierarchy,\n estimateFormat: 'Story points or hours (Original Estimate field)',\n },\n linear: {\n hierarchy: 'Project > Issue > Sub-issue',\n estimateFormat: 'Linear points (0, 1, 2, 3, 5, 8)',\n },\n github: {\n hierarchy: 'Milestone > Issue',\n estimateFormat: 'T-shirt sizes in labels (size:S, size:M, size:L, size:XL)',\n },\n };\n\n return configs[platform] || configs.jira;\n}\n\n/**\n * Get platform-specific type mappings\n */\nexport function getPlatformTypes(platform: string, adoProcess?: string): string {\n const adoConfig = adoProcess ? getAdoProcessConfig(adoProcess) : ADO_PROCESS_CONFIG.agile;\n\n const types: Record<string, string> = {\n jira: 'epic|story|task|bug|subtask',\n ado: adoConfig.types,\n linear: 'project|issue|subissue',\n github: 'milestone|issue',\n };\n\n return types[platform] || types.jira;\n}\n\n/**\n * Generate hierarchy rules for AI prompt based on platform and process\n */\nexport function getHierarchyRules(platform: string, adoProcess?: string): string {\n if (platform === 'ado') {\n switch (adoProcess) {\n case 'basic':\n return `\n- ADO Basic process hierarchy: Epic \\u2192 Issue \\u2192 Task\n- Each EPIC groups related Issues\n- Each ISSUE represents a user-facing feature (use type \"issue\")\n- Each TASK is implementation work\n- EVERY Issue must have parentRef pointing to its Epic's title\n- EVERY Task must have parentRef pointing to its Issue's title\n- Include acceptance criteria for Issues in the acceptanceCriteria field\n- NOTE: Basic process does NOT have Features or User Stories - use Issue instead`;\n\n case 'scrum':\n return `\n- ADO Scrum process hierarchy: Epic \\u2192 Feature \\u2192 Product Backlog Item \\u2192 Task\n- Each EPIC groups related Features\n- Each FEATURE groups related Product Backlog Items (use type \"pbi\")\n- Each TASK is implementation work\n- EVERY Feature must have parentRef pointing to its Epic's title\n- EVERY PBI must have parentRef pointing to its Feature's title\n- EVERY Task must have parentRef pointing to its PBI's title\n- Include acceptance criteria for PBIs in the acceptanceCriteria field`;\n\n case 'cmmi':\n return `\n- ADO CMMI process hierarchy: Epic \\u2192 Feature \\u2192 Requirement \\u2192 Task\n- Each EPIC groups related Features\n- Each FEATURE groups related Requirements (use type \"requirement\")\n- Each TASK is implementation work\n- EVERY Feature must have parentRef pointing to its Epic's title\n- EVERY Requirement must have parentRef pointing to its Feature's title\n- EVERY Task must have parentRef pointing to its Requirement's title\n- Include acceptance criteria for Requirements in the acceptanceCriteria field`;\n\n default: // agile\n return `\n- ADO Agile process hierarchy: Epic \\u2192 Feature \\u2192 User Story \\u2192 Task\n- Each EPIC groups related Features\n- Each FEATURE groups related User Stories (use type \"story\")\n- Each USER STORY has Tasks for implementation\n- EVERY Feature must have parentRef pointing to its Epic's title\n- EVERY Story must have parentRef pointing to its Feature's title\n- EVERY Task must have parentRef pointing to its Story's title\n- Include acceptance criteria for User Stories in the acceptanceCriteria field`;\n }\n }\n\n if (platform === 'jira') {\n return `\n- Jira hierarchy: Epic \\u2192 Story \\u2192 Task/Subtask\n- Each EPIC groups related Stories\n- Each STORY represents a user-facing feature\n- Each TASK/SUBTASK is implementation work\n- EVERY Story must have parentRef pointing to its Epic's title\n- EVERY Task must have parentRef pointing to its Story's title\n- Include acceptance criteria for Stories`;\n }\n\n // Default for linear/github\n return `\n- Create logical parent-child relationships\n- Use parentRef to link children to parents`;\n}\n","/**\n * Config index\n */\n\nexport {\n ADO_PROCESS_CONFIG,\n getAdoProcessConfig,\n getPlatformConfig,\n getPlatformTypes,\n getHierarchyRules,\n} from './platform-config.js';\n","/**\n * Estimate Parser\n *\n * Parses various estimate formats into structured format\n */\n\nimport type { EstimateUnit } from '@vaspera/shared';\n\nexport interface ParsedEstimate {\n value: number;\n unit: EstimateUnit;\n}\n\n/**\n * T-shirt size to story points mapping\n */\nconst T_SHIRT_SIZE_MAP: Record<string, number> = {\n xs: 1,\n s: 2,\n m: 3,\n l: 5,\n xl: 8,\n xxl: 13,\n};\n\n/**\n * Parse estimate string to structured format\n *\n * Supports:\n * - Story points: \"5\", \"5pt\", \"5 points\"\n * - Hours: \"4h\", \"4 hours\"\n * - Days: \"2d\", \"2 days\"\n * - T-shirt sizes: \"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\"\n */\nexport function parseEstimate(estimate: string | undefined): ParsedEstimate | undefined {\n if (!estimate) return undefined;\n\n const normalized = estimate.trim().toLowerCase();\n\n // Story points (number only or with pt/points suffix)\n const pointsMatch = normalized.match(/^(\\d+)\\s*(pts?|points?)?$/i);\n if (pointsMatch) {\n return { value: parseInt(pointsMatch[1], 10), unit: 'points' };\n }\n\n // Hours\n const hoursMatch = normalized.match(/^(\\d+)\\s*h(ours?)?$/i);\n if (hoursMatch) {\n return { value: parseInt(hoursMatch[1], 10), unit: 'hours' };\n }\n\n // Days\n const daysMatch = normalized.match(/^(\\d+)\\s*d(ays?)?$/i);\n if (daysMatch) {\n return { value: parseInt(daysMatch[1], 10), unit: 'days' };\n }\n\n // T-shirt sizes\n const sizeMatch = normalized.match(/^(xs|s|m|l|xl|xxl)$/);\n if (sizeMatch && T_SHIRT_SIZE_MAP[sizeMatch[1]]) {\n return { value: T_SHIRT_SIZE_MAP[sizeMatch[1]], unit: 'points' };\n }\n\n // Default: try to parse as number (story points)\n const numValue = parseInt(estimate, 10);\n if (!isNaN(numValue)) {\n return { value: numValue, unit: 'points' };\n }\n\n return undefined;\n}\n","/**\n * Priority Normalizer\n *\n * Normalizes various priority strings to WorkItemPriority\n */\n\nimport type { WorkItemPriority } from '@vaspera/shared';\n\n/**\n * Map of priority aliases to normalized values\n */\nconst PRIORITY_MAP: Record<string, WorkItemPriority> = {\n // Critical\n highest: 'critical',\n critical: 'critical',\n urgent: 'critical',\n blocker: 'critical',\n\n // High\n high: 'high',\n important: 'high',\n major: 'high',\n\n // Medium\n medium: 'medium',\n normal: 'medium',\n moderate: 'medium',\n\n // Low\n low: 'low',\n lowest: 'low',\n minor: 'low',\n trivial: 'low',\n};\n\n/**\n * Normalize priority string to WorkItemPriority\n *\n * Supports various formats:\n * - Standard: critical, high, medium, low\n * - Jira-style: Highest, High, Medium, Low, Lowest\n * - Descriptive: urgent, important, normal, minor, trivial\n */\nexport function normalizePriority(priority: string | undefined): WorkItemPriority {\n if (!priority) return 'medium';\n\n const normalized = priority.toLowerCase().trim();\n return PRIORITY_MAP[normalized] || 'medium';\n}\n","/**\n * Parsers index\n */\n\nexport { parseEstimate, type ParsedEstimate } from './estimate-parser.js';\nexport { normalizePriority } from './priority-normalizer.js';\n","/**\n * sync-to-tracker module\n *\n * Main entry point for the refactored sync-to-tracker tool\n */\n\n// Export types\nexport type { RawTrackerItem, SyncOutput, AdoProcessConfig, PlatformConfig, SupportedPlatform, AdoProcess } from './types.js';\n\n// Export formatters\nexport { generateCSV, generateMarkdownPreview, getImportInstructions } from './formatters/index.js';\n\n// Export config\nexport { ADO_PROCESS_CONFIG, getAdoProcessConfig, getPlatformConfig, getPlatformTypes, getHierarchyRules } from './config/index.js';\n\n// Export parsers\nexport { parseEstimate, normalizePriority, type ParsedEstimate } from './parsers/index.js';\n","/**\n * sync_to_tracker tool\n *\n * Format requirements for project management tools (Jira, ADO, Linear, GitHub)\n *\n * This is the refactored version using decomposed modules from sync-to-tracker/\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport { createJsonCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport type { TrackerItem, TargetPlatform } from '@vaspera/shared';\nimport { getExporter } from '../output/exporters/index.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n// Import from decomposed modules\nimport {\n type RawTrackerItem,\n type SyncOutput,\n type AdoProcess,\n generateCSV,\n generateMarkdownPreview,\n getImportInstructions,\n getPlatformConfig,\n getPlatformTypes,\n getHierarchyRules,\n parseEstimate,\n normalizePriority,\n} from './sync-to-tracker/index.js';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Build the system prompt for AI completion\n */\nfunction buildSystemPrompt(\n platform: string,\n projectKey: string | undefined,\n epicName: string | undefined,\n defaultLabels: string[],\n includeEstimates: boolean,\n estimateUnit: string,\n adoProcess: string\n): string {\n const config = getPlatformConfig(platform, adoProcess);\n const types = getPlatformTypes(platform, adoProcess);\n const hierarchyRules = getHierarchyRules(platform, adoProcess);\n\n return `You are an expert at structuring work items for project management tools.\n\nConvert the requirements into structured items for ${platform.toUpperCase()}.\n\nPlatform hierarchy: ${config.hierarchy}\nEstimate format: ${config.estimateFormat}\n${epicName ? `Parent Epic: ${epicName}` : ''}\n${defaultLabels.length > 0 ? `Default Labels: ${defaultLabels.join(', ')}` : ''}\n\nOutput a JSON object with this structure:\n{\n \"platform\": \"${platform}\",\n \"projectKey\": \"${projectKey || 'PROJECT'}\",\n \"items\": [\n {\n \"type\": \"${types}\",\n \"title\": \"Clear, actionable title\",\n \"description\": \"Detailed description with context\",\n \"acceptanceCriteria\": [\"Criterion 1\", \"Criterion 2\"],\n \"priority\": \"highest|high|medium|low|lowest\",\n \"labels\": [\"label1\", \"label2\"],\n \"estimate\": \"${includeEstimates ? 'Appropriate estimate' : 'null'}\",\n \"parentRef\": \"ITEM_ID of parent item (required for child items)\",\n \"customFields\": {}\n }\n ],\n \"importInstructions\": \"Step-by-step instructions for importing into ${platform}\"\n}\n\nCRITICAL HIERARCHY RULES:\n${hierarchyRules}\n\nGuidelines:\n- Create items in DEPENDENCY ORDER (parents before children)\n- Write clear, actionable titles (start with verb)\n- Include enough context in descriptions for developers\n- Add 3-5 acceptance criteria for stories/user stories\n- Use appropriate priority based on business value and dependencies\n- Keep items appropriately sized (stories should be completable in 1 sprint)\n- ALWAYS set parentRef for non-epic items\n${includeEstimates ? `- Include ${estimateUnit} estimates based on complexity` : '- Do not include estimates'}`;\n}\n\n/**\n * Normalize raw items from AI to TrackerItem format\n */\nfunction normalizeItems(items: RawTrackerItem[], defaultLabels: string[]): TrackerItem[] {\n // Add default labels to all items\n const itemsWithLabels =\n defaultLabels.length > 0\n ? items.map((item) => ({\n ...item,\n labels: [...new Set([...(item.labels || []), ...defaultLabels])],\n }))\n : items;\n\n return itemsWithLabels.map((item, index) => ({\n id: `VPM-${String(index + 1).padStart(3, '0')}`,\n type: item.type as TrackerItem['type'],\n title: item.title,\n description: item.description,\n acceptanceCriteria: item.acceptanceCriteria || [],\n priority: normalizePriority(item.priority),\n labels: item.labels || [],\n parentId: item.parentRef,\n dependencies: [],\n estimate: item.estimate ? parseEstimate(item.estimate) : undefined,\n customFields: item.customFields,\n }));\n}\n\n/**\n * Generate output in requested format(s)\n */\nfunction generateOutput(\n normalizedItems: TrackerItem[],\n formattedOutput: unknown,\n platform: string,\n projectKey: string,\n outputFormat: string,\n adoProcess: AdoProcess\n): string {\n const outputs: string[] = [];\n\n if (outputFormat === 'json' || outputFormat === 'all') {\n outputs.push('## JSON Export (for API Import)\\n');\n outputs.push('```json');\n outputs.push(JSON.stringify(formattedOutput, null, 2));\n outputs.push('```\\n');\n }\n\n if (outputFormat === 'csv' || outputFormat === 'all') {\n const csv = generateCSV(normalizedItems, platform, adoProcess);\n outputs.push('## CSV Export (for Direct Import)\\n');\n outputs.push('```csv');\n outputs.push(csv);\n outputs.push('```\\n');\n }\n\n if (outputFormat === 'markdown' || outputFormat === 'all') {\n const preview = generateMarkdownPreview(normalizedItems, platform, projectKey);\n outputs.push(preview);\n outputs.push('\\n');\n }\n\n // Always include import instructions\n const instructions = getImportInstructions(platform, projectKey, normalizedItems.length);\n outputs.push(instructions);\n\n return outputs.join('\\n');\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\n/**\n * sync_to_tracker tool - Format requirements for project management tools\n */\nexport const syncToTrackerTool: ToolDefinition = {\n tool: {\n name: 'sync_to_tracker',\n description: `Format requirements and user stories for import into project management tools.\n\nTakes requirements or a PRD and generates properly formatted items for:\n- Jira (Epics, Stories, Tasks, Subtasks)\n- Azure DevOps (Epics, Features, User Stories, Tasks)\n- Linear (Projects, Issues, Sub-issues)\n- GitHub Issues (Issues with labels and milestones)\n\nOutput formats:\n- **JSON**: Structured data for API-based import\n- **CSV**: Direct import via platform UI (Jira CSV importer, ADO Excel import)\n- **Markdown**: Human-readable preview with hierarchy visualization\n- **All**: Combined output with all formats (default)\n\nIncludes platform-specific import instructions with CLI commands and checklists.\n\nBest for: Automated backlog population from requirements documents.`,\n inputSchema: {\n type: 'object',\n properties: {\n requirements: {\n type: 'string',\n description: 'Requirements document, PRD, or user stories to convert',\n },\n platform: {\n type: 'string',\n enum: ['jira', 'ado', 'linear', 'github'],\n default: 'jira',\n description: 'Target project management platform',\n },\n projectKey: {\n type: 'string',\n description: 'Project key/identifier (e.g., PROJ for Jira)',\n },\n epicName: {\n type: 'string',\n description: 'Parent epic name for all generated items',\n },\n defaultLabels: {\n type: 'array',\n items: { type: 'string' },\n description: 'Default labels to apply to all items',\n },\n includeEstimates: {\n type: 'boolean',\n default: true,\n description: 'Whether to include effort estimates',\n },\n estimateUnit: {\n type: 'string',\n enum: ['story_points', 'hours', 't_shirt'],\n default: 'story_points',\n description: 'Estimation unit to use',\n },\n outputFormat: {\n type: 'string',\n enum: ['json', 'csv', 'markdown', 'all'],\n default: 'all',\n description: 'Output format: json (API import), csv (direct import), markdown (human review), all (combined)',\n },\n adoProcess: {\n type: 'string',\n enum: ['basic', 'agile', 'scrum', 'cmmi'],\n default: 'agile',\n description:\n 'ADO process template (basic: Epic→Issue→Task, agile: Epic→Feature→User Story→Task, scrum: Epic→Feature→PBI→Task, cmmi: Epic→Feature→Requirement→Task)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['requirements'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n // Parse arguments\n const requirements = args.requirements as string;\n const platform = (args.platform as string) || 'jira';\n const projectKey = (args.projectKey as string) || undefined;\n const epicName = (args.epicName as string) || undefined;\n const defaultLabels = (args.defaultLabels as string[]) || [];\n const includeEstimates = args.includeEstimates !== false;\n const estimateUnit = (args.estimateUnit as string) || 'story_points';\n const outputFormat = (args.outputFormat as string) || 'all';\n const adoProcess = ((args.adoProcess as string) || 'agile') as AdoProcess;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n // Validate input\n if (!requirements || requirements.trim().length === 0) {\n return errorResult('Requirements content is required');\n }\n\n // Validate platform\n const config = getPlatformConfig(platform, adoProcess);\n if (!config) {\n return errorResult(`Unsupported platform: ${platform}`);\n }\n\n // Build prompts\n const systemPrompt = buildSystemPrompt(\n platform,\n projectKey,\n epicName,\n defaultLabels,\n includeEstimates,\n estimateUnit,\n adoProcess\n );\n\n const userMessage = `Convert these requirements into ${platform} items:\n\n${requirements.length > 12000 ? requirements.substring(0, 12000) + '\\n... [truncated]' : requirements}\n\nGenerate structured items ready for import.`;\n\n try {\n // Call AI\n const result = await createJsonCompletion<SyncOutput>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n const items = result.data.items || [];\n\n // Normalize items\n const normalizedItems = normalizeItems(items, defaultLabels);\n\n // Get platform-specific export format\n const targetPlatform = platform as TargetPlatform;\n const exporter = getExporter(targetPlatform);\n const formattedOutput = exporter.export(normalizedItems, projectKey || 'PROJECT');\n const key = projectKey || 'PROJECT';\n\n // Generate combined output\n const combinedOutput = generateOutput(normalizedItems, formattedOutput, platform, key, outputFormat, adoProcess);\n\n // Save output\n const defaults = getToolDefaults('sync_to_tracker');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'sync_to_tracker',\n category: defaults.category,\n filename: `export_${platform}`,\n content: combinedOutput,\n format: 'md',\n inputs: [platform, outputFormat],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(combinedOutput + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to format for tracker: ${message}`);\n }\n },\n\n requiredScope: 'tools:sync_to_tracker',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * reverse_engineer_user_flows tool - Extract user flows from code\n */\nexport const reverseEngineerFlowsTool: ToolDefinition = {\n tool: {\n name: 'reverse_engineer_user_flows',\n description: `Analyze code to extract and document user flows and journeys.\n\nTakes source code (routes, components, handlers) and produces:\n- User journey maps\n- Flow diagrams (Mermaid)\n- Screen/state transitions\n- API call sequences\n- Error handling paths\n- Edge case flows\n\nBest for: Documenting existing features or understanding inherited codebases.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'Source code to analyze (routes, components, controllers)',\n },\n codeType: {\n type: 'string',\n enum: ['frontend', 'backend', 'fullstack', 'api'],\n default: 'fullstack',\n description: 'Type of code being analyzed',\n },\n featureName: {\n type: 'string',\n description: 'Name of the feature being analyzed',\n },\n outputFormat: {\n type: 'string',\n enum: ['flows', 'diagrams', 'documentation', 'all'],\n default: 'all',\n description: 'What to include in output',\n },\n includeErrorFlows: {\n type: 'boolean',\n default: true,\n description: 'Whether to document error handling flows',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['code'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const code = args.code as string;\n const codeType = (args.codeType as string) || 'fullstack';\n const featureName = args.featureName as string | undefined;\n const outputFormat = (args.outputFormat as string) || 'all';\n const includeErrorFlows = args.includeErrorFlows !== false;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!code || code.trim().length === 0) {\n return errorResult('Source code is required for analysis');\n }\n\n const systemPrompt = `You are a senior engineer expert at reverse engineering user flows from code.\n\nAnalyze the provided code and extract user flows.\n\nOutput Sections:\n1. **Overview**\n - Feature summary\n - Entry points identified\n - Key actors/roles\n\n2. **User Flows**\n - Primary happy path\n - Alternative paths\n ${includeErrorFlows ? '- Error flows and recovery paths' : ''}\n - Edge cases\n\n3. **Flow Diagram** (Mermaid)\n \\`\\`\\`mermaid\n flowchart TD\n Start --> Action --> Decision{Condition}\n Decision -->|Yes| Success\n Decision -->|No| Error\n \\`\\`\\`\n\n4. **State Transitions**\n - UI states (loading, error, success, empty)\n - Data states\n - User state changes\n\n5. **API Sequence** (if applicable)\n \\`\\`\\`mermaid\n sequenceDiagram\n participant User\n participant Frontend\n participant API\n participant Database\n \\`\\`\\`\n\n6. **Components/Screens**\n - List of screens/components involved\n - Their responsibilities\n - Data dependencies\n\n7. **User Stories Derived**\n - Inferred user stories from the code\n\n8. **Gaps & Recommendations**\n - Missing error handling\n - Undocumented edge cases\n - Suggested improvements\n\nCode Type: ${codeType}\n${featureName ? `Feature: ${featureName}` : ''}`;\n\n const userMessage = `Analyze this code and extract user flows:\n\n\\`\\`\\`\n${code.length > 15000 ? code.substring(0, 15000) + '\\n// ... [truncated]' : code}\n\\`\\`\\`\n\nDocument all user flows with diagrams.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('reverse_engineer_user_flows');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'reverse_engineer_user_flows',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [codeType],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to reverse engineer flows: ${message}`);\n }\n },\n\n requiredScope: 'tools:reverse_engineer_flows',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * reverse_engineer_frontend tool - Analyze frontend code to generate structured development stories\n *\n * Takes React/Vue/Next.js component code and produces:\n * - Component inventory with props and types\n * - State management patterns\n * - User flow documentation\n * - API integration points\n * - Frontend stories matching explode_backlog format\n */\nexport const reverseEngineerFrontendTool: ToolDefinition = {\n tool: {\n name: 'reverse_engineer_frontend',\n description: `Analyze frontend code to generate structured development stories.\n\nTakes React/Vue/Next.js component code and produces:\n- Component inventory with props and types\n- State management patterns\n- User flow documentation\n- API integration points\n- Frontend stories matching explode_backlog format\n\nBest for: Documenting existing frontend, onboarding, gap analysis.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'Frontend source code to analyze',\n },\n framework: {\n type: 'string',\n enum: ['react', 'vue', 'nextjs', 'auto'],\n default: 'auto',\n description: 'Frontend framework (auto-detected if not specified)',\n },\n outputStyle: {\n type: 'string',\n enum: ['stories', 'inventory', 'flows', 'all'],\n default: 'all',\n description: 'What to include in output',\n },\n gapAnalysis: {\n type: 'boolean',\n default: false,\n description: 'Compare against requirements to identify missing coverage',\n },\n requirements: {\n type: 'string',\n description: 'Requirements/PRD to compare against (for gap analysis)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root for saving output',\n },\n },\n required: ['code'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const code = args.code as string;\n const framework = (args.framework as string) || 'auto';\n const outputStyle = (args.outputStyle as string) || 'all';\n const gapAnalysis = (args.gapAnalysis as boolean) ?? false;\n const requirements = args.requirements as string | undefined;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!code || code.trim().length === 0) {\n return errorResult('Frontend source code is required for analysis');\n }\n\n if (gapAnalysis && !requirements) {\n return errorResult('Requirements are required when gapAnalysis is enabled');\n }\n\n const gapAnalysisSection = gapAnalysis\n ? `\n\n## 6. Gap Analysis\nCompare the extracted components against the provided requirements and identify:\n- **Components without requirements**: UI elements in code that have no corresponding requirement\n- **Requirements without implementation**: Features specified in requirements but not found in code\n- **Partial implementations**: Components that exist but are missing required functionality\n- **Coverage score**: Percentage of requirements with matching frontend implementation\n\nRequirements to compare against:\n\\`\\`\\`\n${requirements}\n\\`\\`\\`\n`\n : '';\n\n const systemPrompt = `You are an expert frontend engineer who reverse-engineers React/Vue/Next.js components into structured documentation.\n\nFramework: ${framework === 'auto' ? 'Auto-detect from code patterns' : framework}\n\nAnalyze the provided code and extract:\n\n## 1. Component Inventory\nFor each component found:\n- **Name and location**: Component name and file path hints\n- **Type**: page | layout | component | modal | form\n- **Props**: With TypeScript types (inferred if not explicit)\n- **Internal state**: useState, useReducer, or equivalent patterns\n- **Events/handlers**: onClick, onSubmit, onChange, etc.\n- **Child components**: Components used within\n\n## 2. User Flows\n- **Entry points**: Pages, routes, main navigation points\n- **Navigation paths**: How users move between screens\n- **Form submissions**: Data collection and submission flows\n- **API calls and data flow**: How data moves through the UI\n\n## 3. State Management\n- **Local state patterns**: useState, useReducer usage\n- **Context usage**: React Context, Vue provide/inject\n- **External stores**: Redux, Zustand, Pinia, Vuex patterns\n\n## 4. API Integration\n- **API calls**: fetch, axios, or framework-specific patterns\n- **Request/response shapes**: Inferred data structures\n- **Error handling**: How API errors are handled in UI\n- **Loading states**: How loading is shown to users\n\n## 5. Generated Frontend Stories\nFor each significant component, generate a frontend story in this JSON format:\n\n\\`\\`\\`json\n{\n \"title\": \"Component Name\",\n \"type\": \"frontend\",\n \"priority\": \"High|Medium|Low\",\n \"story_points\": 3,\n \"componentSpec\": {\n \"name\": \"ComponentName\",\n \"type\": \"page|component|layout|modal\",\n \"states\": [\"idle\", \"loading\", \"error\", \"success\"],\n \"props\": [{ \"name\": \"propName\", \"type\": \"string\", \"required\": true }],\n \"events\": [{ \"name\": \"onClick\", \"payload\": \"void\" }]\n },\n \"behavior\": {\n \"userFlow\": [\"User sees component\", \"User interacts\", \"Result shown\"],\n \"edgeCases\": [\"Empty state\", \"Error state\"],\n \"accessibility\": [\"Keyboard navigation\", \"Screen reader support\"]\n },\n \"acceptanceCriteria\": [\n \"Given the component is rendered, when user interacts, then expected behavior occurs\"\n ]\n}\n\\`\\`\\`\n${gapAnalysisSection}\n## Output Sections Based on Style: ${outputStyle}\n${outputStyle === 'stories' ? 'Focus on generating frontend stories only.' : ''}\n${outputStyle === 'inventory' ? 'Focus on component inventory and props/state analysis.' : ''}\n${outputStyle === 'flows' ? 'Focus on user flows and state management patterns.' : ''}\n${outputStyle === 'all' ? 'Include all sections: inventory, flows, state, API, and stories.' : ''}`;\n\n const userMessage = `Analyze this frontend code and extract component documentation:\n\n\\`\\`\\`\n${code.length > 20000 ? code.substring(0, 20000) + '\\n// ... [truncated]' : code}\n\\`\\`\\`\n\nGenerate structured frontend documentation and stories.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: gapAnalysis ? 8192 : 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('reverse_engineer_frontend');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'reverse_engineer_frontend',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [framework, outputStyle],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to reverse engineer frontend: ${message}`);\n }\n },\n\n requiredScope: 'tools:reverse_engineer_frontend',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * generate_test_specs tool - Create comprehensive test specifications\n */\nexport const generateTestSpecsTool: ToolDefinition = {\n tool: {\n name: 'generate_test_specs',\n description: `Generate comprehensive test specifications from requirements or code.\n\nTakes PRD, user stories, or source code and produces:\n- Test plan overview\n- Unit test specifications\n- Integration test scenarios\n- E2E test cases\n- Edge case coverage\n- Test data requirements\n- Accessibility testing checklist\n\nBest for: Ensuring comprehensive test coverage before or during development.`,\n inputSchema: {\n type: 'object',\n properties: {\n input: {\n type: 'string',\n description: 'PRD, user stories, or source code to generate tests from',\n },\n inputType: {\n type: 'string',\n enum: ['prd', 'user_stories', 'code', 'api_spec'],\n default: 'prd',\n description: 'Type of input provided',\n },\n testTypes: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['unit', 'integration', 'e2e', 'api', 'performance', 'security', 'accessibility'],\n },\n default: ['unit', 'integration', 'e2e'],\n description: 'Types of tests to generate',\n },\n framework: {\n type: 'string',\n enum: ['jest', 'vitest', 'pytest', 'playwright', 'cypress', 'generic'],\n default: 'generic',\n description: 'Testing framework for syntax hints',\n },\n coverage: {\n type: 'string',\n enum: ['minimal', 'standard', 'comprehensive'],\n default: 'standard',\n description: 'How thorough the test coverage should be',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['input'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const input = args.input as string;\n const inputType = (args.inputType as string) || 'prd';\n const testTypes = (args.testTypes as string[]) || ['unit', 'integration', 'e2e'];\n const framework = (args.framework as string) || 'generic';\n const coverage = (args.coverage as string) || 'standard';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!input || input.trim().length === 0) {\n return errorResult('Input (PRD, user stories, or code) is required');\n }\n\n const coverageGuide: Record<string, string> = {\n minimal: 'Focus on happy paths and critical functionality only',\n standard: 'Cover happy paths, common edge cases, and error scenarios',\n comprehensive: 'Cover all paths, edge cases, error scenarios, boundary conditions, and negative testing',\n };\n\n const systemPrompt = `You are a QA architect expert at creating comprehensive test specifications.\n\nGenerate test specs from the provided ${inputType}.\n\nTest Types to Include: ${testTypes.join(', ')}\nFramework: ${framework}\nCoverage Level: ${coverageGuide[coverage]}\n\nOutput Sections:\n\n1. **Test Plan Overview**\n - Scope and objectives\n - Test strategy\n - Risk-based prioritization\n\n2. **Unit Tests** (if requested)\n - Function/method level tests\n - Mock requirements\n - Edge cases per function\n ${framework !== 'generic' ? `- ${framework} code snippets` : ''}\n\n3. **Integration Tests** (if requested)\n - Component interaction tests\n - API contract tests\n - Database integration tests\n\n4. **E2E Tests** (if requested)\n - User journey scenarios\n - Critical path coverage\n - Cross-browser/device requirements\n\n5. **API Tests** (if requested)\n - Endpoint coverage\n - Request/response validation\n - Error response testing\n\n6. **Performance Tests** (if requested)\n - Load testing scenarios\n - Response time expectations\n - Concurrent user tests\n\n7. **Security Tests** (if requested)\n - Authentication/authorization tests\n - Input validation tests\n - OWASP considerations\n\n8. **Accessibility Tests** (if requested)\n - WCAG compliance checks\n - Screen reader compatibility\n - Keyboard navigation\n\n9. **Test Data Requirements**\n - Fixtures needed\n - Test user personas\n - Mock data specifications\n\n10. **Acceptance Criteria Traceability**\n - Map each test to a requirement\n - Coverage matrix\n\nFormat each test case as:\n\\`\\`\\`\nTest ID: TC-XXX\nTitle: [Descriptive title]\nPreconditions: [Setup required]\nSteps:\n1. [Action]\n2. [Action]\nExpected Result: [What should happen]\nPriority: High/Medium/Low\n\\`\\`\\``;\n\n const userMessage = `Generate test specifications from this ${inputType}:\n\n${input.length > 12000 ? input.substring(0, 12000) + '\\n... [truncated]' : input}\n\nCreate comprehensive test specs covering: ${testTypes.join(', ')}`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('generate_test_specs');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_test_specs',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: testTypes,\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate test specs: ${message}`);\n }\n },\n\n requiredScope: 'tools:generate_test_specs',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * explain_codebase tool - Generate comprehensive codebase documentation\n */\nexport const explainCodebaseTool: ToolDefinition = {\n tool: {\n name: 'explain_codebase',\n description: `Analyze code and generate comprehensive documentation for product managers.\n\nTakes source code and produces PM-friendly documentation:\n- Architecture overview\n- Feature inventory\n- Data flow explanations\n- User-facing functionality mapping\n- Technical debt assessment\n- Business logic documentation\n\nBest for: Onboarding PMs to existing codebases or creating technical context.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'Source code to analyze and explain',\n },\n projectName: {\n type: 'string',\n description: 'Name of the project',\n },\n codeContext: {\n type: 'string',\n description: 'Additional context about the codebase',\n },\n audience: {\n type: 'string',\n enum: ['pm', 'stakeholder', 'new_engineer', 'executive'],\n default: 'pm',\n description: 'Target audience for the documentation',\n },\n focus: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'architecture',\n 'features',\n 'data_flow',\n 'business_logic',\n 'tech_debt',\n 'dependencies',\n 'security',\n ],\n },\n default: ['architecture', 'features', 'business_logic'],\n description: 'Areas to focus documentation on',\n },\n detailLevel: {\n type: 'string',\n enum: ['overview', 'detailed', 'deep_dive'],\n default: 'detailed',\n description: 'Level of detail in explanations',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['code'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const code = args.code as string;\n const projectName = args.projectName as string | undefined;\n const codeContext = args.codeContext as string | undefined;\n const audience = (args.audience as string) || 'pm';\n const focus = (args.focus as string[]) || ['architecture', 'features', 'business_logic'];\n const detailLevel = (args.detailLevel as string) || 'detailed';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!code || code.trim().length === 0) {\n return errorResult('Source code is required for analysis');\n }\n\n const audienceGuide: Record<string, string> = {\n pm: 'Focus on product features, user value, and business logic. Avoid deep technical jargon.',\n stakeholder: 'High-level overview focusing on capabilities, risks, and business implications.',\n new_engineer: 'Technical detail with onboarding focus. Explain patterns, conventions, and gotchas.',\n executive: 'Strategic summary focusing on capabilities, technical health, and risks.',\n };\n\n const systemPrompt = `You are a staff engineer who excels at explaining complex codebases to non-technical stakeholders.\n\nAnalyze the code and create documentation for: ${audience}\n${audienceGuide[audience]}\n\nDocumentation Focus: ${focus.join(', ')}\nDetail Level: ${detailLevel}\n${projectName ? `Project: ${projectName}` : ''}\n${codeContext ? `Context: ${codeContext}` : ''}\n\nOutput Sections (include based on focus):\n\n1. **Executive Summary**\n - What this code does in plain English\n - Key capabilities\n - Technology stack\n\n2. **Architecture Overview** (if in focus)\n - System diagram (Mermaid)\n - Key components and their roles\n - How pieces fit together\n\n3. **Feature Inventory** (if in focus)\n - List of user-facing features found\n - Feature completeness assessment\n - Hidden/admin features\n\n4. **Data Flow** (if in focus)\n - How data moves through the system\n - Key entities and relationships\n - Data transformations\n\n5. **Business Logic Documentation** (if in focus)\n - Core algorithms explained\n - Business rules implemented\n - Validation and constraints\n\n6. **Technical Debt Assessment** (if in focus)\n - Code quality observations\n - Maintenance concerns\n - Refactoring opportunities\n\n7. **Dependencies** (if in focus)\n - External services used\n - Third-party libraries\n - Integration points\n\n8. **Security Considerations** (if in focus)\n - Authentication/authorization patterns\n - Data protection measures\n - Potential concerns\n\n9. **Glossary**\n - Technical terms explained\n - Domain-specific vocabulary\n\nGuidelines:\n- Use analogies for complex concepts\n- Include \"What this means for product\" sections\n- Highlight risks and opportunities\n- Be honest about limitations and unknowns`;\n\n const userMessage = `Analyze and document this codebase:\n\n\\`\\`\\`\n${code.length > 15000 ? code.substring(0, 15000) + '\\n// ... [truncated]' : code}\n\\`\\`\\`\n\nCreate comprehensive documentation for a ${audience}.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('explain_codebase');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'explain_codebase',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: focus,\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to explain codebase: ${message}`);\n }\n },\n\n requiredScope: 'tools:explain_codebase',\n};\n","/**\n * AST Types\n *\n * Structured representation of code for efficient analysis.\n * These types provide a compact, AI-friendly format that:\n * - Reduces token usage vs raw code\n * - Enables precise matching to documentation\n * - Supports framework-specific extraction\n */\n\n// ============================================================================\n// File-Level Types\n// ============================================================================\n\nexport interface CodeAST {\n /** File metadata */\n file: FileMetadata;\n\n /** What this file exposes */\n exports: Export[];\n\n /** All function definitions */\n functions: FunctionDef[];\n\n /** All class definitions */\n classes: ClassDef[];\n\n /** API routes (framework-specific) */\n routes: RouteDef[];\n\n /** Important constant values */\n constants: ConstantDef[];\n\n /** Type definitions (TypeScript/Flow) */\n types: TypeDef[];\n\n /** Documentation comments (JSDoc, docstrings) */\n docComments: DocComment[];\n\n /** Import statements */\n imports: ImportDef[];\n}\n\nexport interface FileMetadata {\n path: string;\n relativePath: string;\n language: 'typescript' | 'javascript' | 'python' | 'go' | 'java' | 'rust';\n framework?: string;\n size: number;\n lastModified?: Date;\n hash?: string;\n}\n\n// ============================================================================\n// Export Types\n// ============================================================================\n\nexport interface Export {\n name: string;\n type: 'function' | 'class' | 'const' | 'type' | 'interface' | 'enum' | 'default' | 'namespace';\n isDefault: boolean;\n isReExport: boolean;\n from?: string; // For re-exports\n lineNumber: number;\n}\n\n// ============================================================================\n// Function Types\n// ============================================================================\n\nexport interface FunctionDef {\n name: string;\n params: Parameter[];\n returnType?: string;\n isAsync: boolean;\n isGenerator: boolean;\n isExported: boolean;\n visibility: 'public' | 'private' | 'protected';\n docComment?: string;\n decorators?: string[];\n lineStart: number;\n lineEnd: number;\n complexity?: number; // Cyclomatic complexity\n bodyPreview?: string; // First 100 chars of body\n}\n\nexport interface Parameter {\n name: string;\n type?: string;\n isOptional: boolean;\n defaultValue?: string;\n isRest: boolean;\n}\n\n// ============================================================================\n// Class Types\n// ============================================================================\n\nexport interface ClassDef {\n name: string;\n isExported: boolean;\n isAbstract: boolean;\n extends?: string;\n implements?: string[];\n decorators?: string[];\n docComment?: string;\n methods: MethodDef[];\n properties: PropertyDef[];\n lineStart: number;\n lineEnd: number;\n}\n\nexport interface MethodDef extends FunctionDef {\n isStatic: boolean;\n isAbstract: boolean;\n visibility: 'public' | 'private' | 'protected';\n}\n\nexport interface PropertyDef {\n name: string;\n type?: string;\n isStatic: boolean;\n isReadonly: boolean;\n visibility: 'public' | 'private' | 'protected';\n defaultValue?: string;\n lineNumber: number;\n}\n\n// ============================================================================\n// Route Types (Framework-Specific)\n// ============================================================================\n\nexport interface RouteDef {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'ALL';\n path: string;\n handler: string;\n handlerFile?: string;\n middleware?: string[];\n params?: RouteParam[];\n queryParams?: RouteParam[];\n requestBody?: TypeRef;\n responseType?: TypeRef;\n statusCodes?: number[];\n docComment?: string;\n lineNumber: number;\n framework: 'nextjs' | 'express' | 'fastify' | 'hono' | 'django' | 'flask' | 'fastapi' | 'gin' | 'other';\n}\n\nexport interface RouteParam {\n name: string;\n type?: string;\n required: boolean;\n description?: string;\n validation?: string;\n}\n\nexport interface TypeRef {\n name: string;\n isArray: boolean;\n properties?: Record<string, string>;\n schema?: string; // JSON Schema or Zod/Joi reference\n}\n\n// ============================================================================\n// Constant Types\n// ============================================================================\n\nexport interface ConstantDef {\n name: string;\n value: unknown;\n type?: string;\n isExported: boolean;\n category: 'config' | 'limit' | 'feature_flag' | 'env' | 'other';\n docComment?: string;\n lineNumber: number;\n}\n\n// ============================================================================\n// Type Definition Types\n// ============================================================================\n\nexport interface TypeDef {\n name: string;\n kind: 'type' | 'interface' | 'enum';\n isExported: boolean;\n properties?: TypeProperty[];\n enumValues?: EnumValue[];\n extends?: string[];\n docComment?: string;\n lineStart: number;\n lineEnd: number;\n}\n\nexport interface TypeProperty {\n name: string;\n type: string;\n isOptional: boolean;\n isReadonly: boolean;\n docComment?: string;\n}\n\nexport interface EnumValue {\n name: string;\n value?: string | number;\n}\n\n// ============================================================================\n// Import Types\n// ============================================================================\n\nexport interface ImportDef {\n source: string;\n isRelative: boolean;\n isTypeOnly: boolean;\n defaultImport?: string;\n namedImports?: string[];\n namespaceImport?: string;\n lineNumber: number;\n}\n\n// ============================================================================\n// Documentation Types\n// ============================================================================\n\nexport interface DocComment {\n content: string;\n associatedWith?: string; // Name of function/class/etc\n tags?: DocTag[];\n lineStart: number;\n lineEnd: number;\n}\n\nexport interface DocTag {\n tag: string; // @param, @returns, @example, etc\n name?: string;\n type?: string;\n description?: string;\n}\n\n// ============================================================================\n// Framework Extractor Interface\n// ============================================================================\n\nexport interface FrameworkExtractor {\n /** Framework name */\n name: string;\n\n /** Detect if this extractor applies to the file */\n canHandle(file: FileMetadata, content: string): boolean;\n\n /** Extract routes from the AST */\n extractRoutes(ast: CodeAST, content: string): RouteDef[];\n\n /** Extract middleware definitions */\n extractMiddleware?(ast: CodeAST, content: string): MiddlewareDef[];\n\n /** Extract server actions (Next.js specific) */\n extractServerActions?(ast: CodeAST, content: string): ServerActionDef[];\n}\n\nexport interface MiddlewareDef {\n name: string;\n matcher?: string | string[];\n order?: number;\n docComment?: string;\n lineNumber: number;\n}\n\nexport interface ServerActionDef {\n name: string;\n params: Parameter[];\n returnType?: string;\n docComment?: string;\n lineNumber: number;\n}\n\n// ============================================================================\n// AST Summary (Compact Format for AI)\n// ============================================================================\n\nexport interface ASTSummary {\n file: string;\n language: string;\n framework?: string;\n\n /** Quick stats */\n stats: {\n functions: number;\n classes: number;\n routes: number;\n exports: number;\n types: number;\n constants: number;\n complexity: number; // Total cyclomatic complexity\n };\n\n /** Key items (most important for verification) */\n highlights: {\n publicFunctions: string[];\n routes: string[];\n configConstants: string[];\n exportedTypes: string[];\n };\n}\n","/**\n * TypeScript AST Parser\n *\n * Extracts structured information from TypeScript/JavaScript files\n * using @typescript-eslint/parser for accurate parsing.\n */\n\nimport { parse } from '@typescript-eslint/parser';\nimport type { TSESTree } from '@typescript-eslint/types';\nimport {\n CodeAST,\n FileMetadata,\n Export,\n FunctionDef,\n ClassDef,\n MethodDef,\n PropertyDef,\n ConstantDef,\n TypeDef,\n TypeProperty,\n ImportDef,\n DocComment,\n Parameter,\n ASTSummary,\n} from './types.js';\n\n// ============================================================================\n// Parser Configuration\n// ============================================================================\n\nconst PARSER_OPTIONS = {\n ecmaVersion: 2022 as const,\n sourceType: 'module' as const,\n ecmaFeatures: {\n jsx: true,\n },\n range: true,\n loc: true,\n comment: true,\n};\n\n// ============================================================================\n// Main Parser\n// ============================================================================\n\nexport class TypeScriptParser {\n /**\n * Parse a TypeScript/JavaScript file into structured AST\n */\n parse(content: string, metadata: FileMetadata): CodeAST {\n const isTypeScript = metadata.language === 'typescript' ||\n metadata.path.endsWith('.ts') ||\n metadata.path.endsWith('.tsx');\n\n const ast = parse(content, {\n ...PARSER_OPTIONS,\n jsx: metadata.path.endsWith('.tsx') || metadata.path.endsWith('.jsx'),\n });\n\n const comments = this.extractComments(ast.comments || []);\n\n return {\n file: metadata,\n exports: this.extractExports(ast, content),\n functions: this.extractFunctions(ast, comments),\n classes: this.extractClasses(ast, comments),\n routes: [], // Populated by framework extractors\n constants: this.extractConstants(ast, comments),\n types: isTypeScript ? this.extractTypes(ast, comments) : [],\n docComments: comments,\n imports: this.extractImports(ast),\n };\n }\n\n /**\n * Generate a compact summary for AI consumption\n */\n summarize(ast: CodeAST): ASTSummary {\n const totalComplexity = ast.functions.reduce(\n (sum, f) => sum + (f.complexity || 1),\n 0\n );\n\n return {\n file: ast.file.relativePath,\n language: ast.file.language,\n framework: ast.file.framework,\n stats: {\n functions: ast.functions.length,\n classes: ast.classes.length,\n routes: ast.routes.length,\n exports: ast.exports.length,\n types: ast.types.length,\n constants: ast.constants.length,\n complexity: totalComplexity,\n },\n highlights: {\n publicFunctions: ast.functions\n .filter((f) => f.isExported)\n .map((f) => `${f.name}(${f.params.map((p) => p.name).join(', ')})`),\n routes: ast.routes.map((r) => `${r.method} ${r.path}`),\n configConstants: ast.constants\n .filter((c) => c.category === 'config' || c.category === 'limit')\n .map((c) => `${c.name}: ${JSON.stringify(c.value)}`),\n exportedTypes: ast.types\n .filter((t) => t.isExported)\n .map((t) => t.name),\n },\n };\n }\n\n // ==========================================================================\n // Export Extraction\n // ==========================================================================\n\n private extractExports(ast: TSESTree.Program, content: string): Export[] {\n const exports: Export[] = [];\n\n for (const node of ast.body) {\n if (node.type === 'ExportNamedDeclaration') {\n if (node.declaration) {\n const exp = this.exportFromDeclaration(node.declaration, false);\n if (exp) exports.push({ ...exp, lineNumber: node.loc?.start.line || 0 });\n }\n for (const spec of node.specifiers || []) {\n exports.push({\n name: spec.exported.type === 'Identifier' ? spec.exported.name : String(spec.exported.value),\n type: 'const',\n isDefault: false,\n isReExport: !!node.source,\n from: node.source?.value as string | undefined,\n lineNumber: node.loc?.start.line || 0,\n });\n }\n } else if (node.type === 'ExportDefaultDeclaration') {\n const exp = this.exportFromDeclaration(node.declaration, true);\n if (exp) {\n exports.push({ ...exp, lineNumber: node.loc?.start.line || 0 });\n } else {\n exports.push({\n name: 'default',\n type: 'default',\n isDefault: true,\n isReExport: false,\n lineNumber: node.loc?.start.line || 0,\n });\n }\n } else if (node.type === 'ExportAllDeclaration') {\n exports.push({\n name: '*',\n type: 'namespace',\n isDefault: false,\n isReExport: true,\n from: node.source.value as string,\n lineNumber: node.loc?.start.line || 0,\n });\n }\n }\n\n return exports;\n }\n\n private exportFromDeclaration(\n decl: TSESTree.ExportDeclaration['declaration'],\n isDefault: boolean\n ): Omit<Export, 'lineNumber'> | null {\n if (!decl) return null;\n\n if (decl.type === 'FunctionDeclaration') {\n return {\n name: decl.id?.name || 'default',\n type: 'function',\n isDefault,\n isReExport: false,\n };\n }\n if (decl.type === 'ClassDeclaration') {\n return {\n name: decl.id?.name || 'default',\n type: 'class',\n isDefault,\n isReExport: false,\n };\n }\n if (decl.type === 'VariableDeclaration') {\n const first = decl.declarations[0];\n if (first?.id.type === 'Identifier') {\n return {\n name: first.id.name,\n type: 'const',\n isDefault,\n isReExport: false,\n };\n }\n }\n if (decl.type === 'TSTypeAliasDeclaration') {\n return {\n name: decl.id.name,\n type: 'type',\n isDefault,\n isReExport: false,\n };\n }\n if (decl.type === 'TSInterfaceDeclaration') {\n return {\n name: decl.id.name,\n type: 'interface',\n isDefault,\n isReExport: false,\n };\n }\n if (decl.type === 'TSEnumDeclaration') {\n return {\n name: decl.id.name,\n type: 'enum',\n isDefault,\n isReExport: false,\n };\n }\n\n return null;\n }\n\n // ==========================================================================\n // Function Extraction\n // ==========================================================================\n\n private extractFunctions(\n ast: TSESTree.Program,\n comments: DocComment[]\n ): FunctionDef[] {\n const functions: FunctionDef[] = [];\n\n const visit = (node: TSESTree.Node, isExported = false): void => {\n if (\n node.type === 'FunctionDeclaration' ||\n node.type === 'FunctionExpression' ||\n node.type === 'ArrowFunctionExpression'\n ) {\n const funcDef = this.extractFunctionDef(node, isExported, comments);\n if (funcDef) functions.push(funcDef);\n }\n\n if (node.type === 'VariableDeclaration') {\n for (const decl of node.declarations) {\n if (\n decl.init &&\n (decl.init.type === 'FunctionExpression' ||\n decl.init.type === 'ArrowFunctionExpression')\n ) {\n const name =\n decl.id.type === 'Identifier' ? decl.id.name : 'anonymous';\n const funcDef = this.extractFunctionDef(decl.init, isExported, comments, name);\n if (funcDef) functions.push(funcDef);\n }\n }\n }\n\n if (node.type === 'ExportNamedDeclaration' && node.declaration) {\n visit(node.declaration, true);\n return;\n }\n\n if (node.type === 'ExportDefaultDeclaration') {\n visit(node.declaration as TSESTree.Node, true);\n return;\n }\n\n // Traverse children\n for (const key of Object.keys(node)) {\n const value = (node as Record<string, unknown>)[key];\n if (value && typeof value === 'object') {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as TSESTree.Node, isExported);\n }\n }\n } else if ('type' in value) {\n visit(value as TSESTree.Node, isExported);\n }\n }\n }\n };\n\n for (const node of ast.body) {\n visit(node);\n }\n\n return functions;\n }\n\n private extractFunctionDef(\n node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression,\n isExported: boolean,\n comments: DocComment[],\n overrideName?: string\n ): FunctionDef | null {\n const name =\n overrideName ||\n (node.type === 'FunctionDeclaration' && node.id?.name) ||\n 'anonymous';\n\n if (name === 'anonymous') return null;\n\n const params = this.extractParams(node.params);\n const returnType = this.extractReturnType(node);\n const docComment = this.findDocComment(comments, node.loc?.start.line || 0);\n\n return {\n name,\n params,\n returnType,\n isAsync: node.async || false,\n isGenerator: 'generator' in node ? node.generator || false : false,\n isExported,\n visibility: 'public',\n docComment,\n lineStart: node.loc?.start.line || 0,\n lineEnd: node.loc?.end.line || 0,\n complexity: this.calculateComplexity(node),\n };\n }\n\n private extractParams(params: TSESTree.Parameter[]): Parameter[] {\n return params.map((param) => {\n if (param.type === 'Identifier') {\n return {\n name: param.name,\n type: param.typeAnnotation\n ? this.typeToString(param.typeAnnotation.typeAnnotation)\n : undefined,\n isOptional: param.optional || false,\n isRest: false,\n };\n }\n if (param.type === 'RestElement' && param.argument.type === 'Identifier') {\n return {\n name: param.argument.name,\n type: param.typeAnnotation\n ? this.typeToString(param.typeAnnotation.typeAnnotation)\n : undefined,\n isOptional: false,\n isRest: true,\n };\n }\n if (param.type === 'AssignmentPattern' && param.left.type === 'Identifier') {\n return {\n name: param.left.name,\n type: param.left.typeAnnotation\n ? this.typeToString(param.left.typeAnnotation.typeAnnotation)\n : undefined,\n isOptional: true,\n defaultValue: this.nodeToString(param.right),\n isRest: false,\n };\n }\n return {\n name: 'param',\n isOptional: false,\n isRest: false,\n };\n });\n }\n\n private extractReturnType(\n node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression\n ): string | undefined {\n if (node.returnType) {\n return this.typeToString(node.returnType.typeAnnotation);\n }\n return undefined;\n }\n\n // ==========================================================================\n // Class Extraction\n // ==========================================================================\n\n private extractClasses(\n ast: TSESTree.Program,\n comments: DocComment[]\n ): ClassDef[] {\n const classes: ClassDef[] = [];\n\n for (const node of ast.body) {\n let classNode: TSESTree.ClassDeclaration | null = null;\n let isExported = false;\n\n if (node.type === 'ClassDeclaration') {\n classNode = node;\n } else if (node.type === 'ExportNamedDeclaration' && node.declaration?.type === 'ClassDeclaration') {\n classNode = node.declaration;\n isExported = true;\n } else if (node.type === 'ExportDefaultDeclaration' && node.declaration.type === 'ClassDeclaration') {\n classNode = node.declaration;\n isExported = true;\n }\n\n if (classNode && classNode.id) {\n const docComment = this.findDocComment(comments, classNode.loc?.start.line || 0);\n\n classes.push({\n name: classNode.id.name,\n isExported,\n isAbstract: classNode.abstract || false,\n extends: classNode.superClass?.type === 'Identifier' ? classNode.superClass.name : undefined,\n implements: this.extractImplements(classNode),\n decorators: this.extractDecorators(classNode),\n docComment,\n methods: this.extractMethods(classNode, comments),\n properties: this.extractProperties(classNode),\n lineStart: classNode.loc?.start.line || 0,\n lineEnd: classNode.loc?.end.line || 0,\n });\n }\n }\n\n return classes;\n }\n\n private extractMethods(\n classNode: TSESTree.ClassDeclaration,\n comments: DocComment[]\n ): MethodDef[] {\n const methods: MethodDef[] = [];\n\n for (const member of classNode.body.body) {\n if (member.type === 'MethodDefinition' && member.key.type === 'Identifier') {\n const docComment = this.findDocComment(comments, member.loc?.start.line || 0);\n\n methods.push({\n name: member.key.name,\n params: this.extractParams(member.value.params),\n returnType: this.extractReturnType(member.value),\n isAsync: member.value.async || false,\n isGenerator: member.value.generator || false,\n isExported: true,\n isStatic: member.static || false,\n isAbstract: false,\n visibility: this.getVisibility(member),\n docComment,\n lineStart: member.loc?.start.line || 0,\n lineEnd: member.loc?.end.line || 0,\n });\n }\n }\n\n return methods;\n }\n\n private extractProperties(classNode: TSESTree.ClassDeclaration): PropertyDef[] {\n const properties: PropertyDef[] = [];\n\n for (const member of classNode.body.body) {\n if (member.type === 'PropertyDefinition' && member.key.type === 'Identifier') {\n properties.push({\n name: member.key.name,\n type: member.typeAnnotation\n ? this.typeToString(member.typeAnnotation.typeAnnotation)\n : undefined,\n isStatic: member.static || false,\n isReadonly: member.readonly || false,\n visibility: this.getVisibility(member),\n defaultValue: member.value ? this.nodeToString(member.value) : undefined,\n lineNumber: member.loc?.start.line || 0,\n });\n }\n }\n\n return properties;\n }\n\n private getVisibility(\n member: TSESTree.MethodDefinition | TSESTree.PropertyDefinition\n ): 'public' | 'private' | 'protected' {\n if (member.accessibility === 'private') return 'private';\n if (member.accessibility === 'protected') return 'protected';\n return 'public';\n }\n\n private extractImplements(classNode: TSESTree.ClassDeclaration): string[] | undefined {\n if (!classNode.implements || classNode.implements.length === 0) {\n return undefined;\n }\n return classNode.implements.map((impl) => {\n if (impl.expression.type === 'Identifier') {\n return impl.expression.name;\n }\n return 'unknown';\n });\n }\n\n private extractDecorators(classNode: TSESTree.ClassDeclaration): string[] | undefined {\n if (!classNode.decorators || classNode.decorators.length === 0) {\n return undefined;\n }\n return classNode.decorators.map((dec) => {\n if (dec.expression.type === 'Identifier') {\n return `@${dec.expression.name}`;\n }\n if (dec.expression.type === 'CallExpression' && dec.expression.callee.type === 'Identifier') {\n return `@${dec.expression.callee.name}(...)`;\n }\n return '@unknown';\n });\n }\n\n // ==========================================================================\n // Constant Extraction\n // ==========================================================================\n\n private extractConstants(\n ast: TSESTree.Program,\n comments: DocComment[]\n ): ConstantDef[] {\n const constants: ConstantDef[] = [];\n\n for (const node of ast.body) {\n let varNode: TSESTree.VariableDeclaration | null = null;\n let isExported = false;\n\n if (node.type === 'VariableDeclaration' && node.kind === 'const') {\n varNode = node;\n } else if (\n node.type === 'ExportNamedDeclaration' &&\n node.declaration?.type === 'VariableDeclaration' &&\n node.declaration.kind === 'const'\n ) {\n varNode = node.declaration;\n isExported = true;\n }\n\n if (varNode) {\n for (const decl of varNode.declarations) {\n if (decl.id.type === 'Identifier' && decl.init) {\n const value = this.extractConstantValue(decl.init);\n const name = decl.id.name;\n const docComment = this.findDocComment(comments, decl.loc?.start.line || 0);\n\n constants.push({\n name,\n value,\n type: decl.id.typeAnnotation\n ? this.typeToString(decl.id.typeAnnotation.typeAnnotation)\n : typeof value,\n isExported,\n category: this.categorizeConstant(name, value),\n docComment,\n lineNumber: decl.loc?.start.line || 0,\n });\n }\n }\n }\n }\n\n return constants;\n }\n\n private extractConstantValue(node: TSESTree.Expression): unknown {\n if (node.type === 'Literal') {\n return node.value;\n }\n if (node.type === 'ObjectExpression') {\n const obj: Record<string, unknown> = {};\n for (const prop of node.properties) {\n if (\n prop.type === 'Property' &&\n prop.key.type === 'Identifier' &&\n prop.value.type === 'Literal'\n ) {\n obj[prop.key.name] = prop.value.value;\n }\n }\n return obj;\n }\n if (node.type === 'ArrayExpression') {\n return node.elements\n .filter((el): el is TSESTree.Expression => el !== null && el.type !== 'SpreadElement')\n .map((el) => this.extractConstantValue(el));\n }\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis.map((q) => q.value.cooked).join('');\n }\n return undefined;\n }\n\n private categorizeConstant(\n name: string,\n value: unknown\n ): ConstantDef['category'] {\n const nameLower = name.toLowerCase();\n\n if (nameLower.includes('limit') || nameLower.includes('max') || nameLower.includes('min')) {\n return 'limit';\n }\n if (nameLower.includes('config') || nameLower.includes('options') || nameLower.includes('settings')) {\n return 'config';\n }\n if (nameLower.includes('feature') || nameLower.includes('flag') || nameLower.includes('enable')) {\n return 'feature_flag';\n }\n if (nameLower.includes('env') || nameLower.startsWith('process_')) {\n return 'env';\n }\n\n return 'other';\n }\n\n // ==========================================================================\n // Type Extraction\n // ==========================================================================\n\n private extractTypes(\n ast: TSESTree.Program,\n comments: DocComment[]\n ): TypeDef[] {\n const types: TypeDef[] = [];\n\n for (const node of ast.body) {\n let typeNode: TSESTree.TSTypeAliasDeclaration | TSESTree.TSInterfaceDeclaration | TSESTree.TSEnumDeclaration | null = null;\n let isExported = false;\n\n if (\n node.type === 'TSTypeAliasDeclaration' ||\n node.type === 'TSInterfaceDeclaration' ||\n node.type === 'TSEnumDeclaration'\n ) {\n typeNode = node;\n } else if (node.type === 'ExportNamedDeclaration' && node.declaration) {\n if (\n node.declaration.type === 'TSTypeAliasDeclaration' ||\n node.declaration.type === 'TSInterfaceDeclaration' ||\n node.declaration.type === 'TSEnumDeclaration'\n ) {\n typeNode = node.declaration;\n isExported = true;\n }\n }\n\n if (typeNode) {\n const docComment = this.findDocComment(comments, typeNode.loc?.start.line || 0);\n\n if (typeNode.type === 'TSInterfaceDeclaration') {\n types.push({\n name: typeNode.id.name,\n kind: 'interface',\n isExported,\n properties: this.extractTypeProperties(typeNode.body),\n extends: typeNode.extends?.map((ext) =>\n ext.expression.type === 'Identifier' ? ext.expression.name : 'unknown'\n ),\n docComment,\n lineStart: typeNode.loc?.start.line || 0,\n lineEnd: typeNode.loc?.end.line || 0,\n });\n } else if (typeNode.type === 'TSTypeAliasDeclaration') {\n types.push({\n name: typeNode.id.name,\n kind: 'type',\n isExported,\n properties: typeNode.typeAnnotation.type === 'TSTypeLiteral'\n ? this.extractTypeProperties(typeNode.typeAnnotation)\n : undefined,\n docComment,\n lineStart: typeNode.loc?.start.line || 0,\n lineEnd: typeNode.loc?.end.line || 0,\n });\n } else if (typeNode.type === 'TSEnumDeclaration') {\n types.push({\n name: typeNode.id.name,\n kind: 'enum',\n isExported,\n enumValues: typeNode.members.map((m) => ({\n name: m.id.type === 'Identifier' ? m.id.name : String((m.id as TSESTree.Literal).value),\n value: m.initializer?.type === 'Literal' ? m.initializer.value as string | number : undefined,\n })),\n docComment,\n lineStart: typeNode.loc?.start.line || 0,\n lineEnd: typeNode.loc?.end.line || 0,\n });\n }\n }\n }\n\n return types;\n }\n\n private extractTypeProperties(\n body: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral\n ): TypeProperty[] {\n const props: TypeProperty[] = [];\n const members = body.type === 'TSInterfaceBody' ? body.body : body.members;\n\n for (const member of members) {\n if (member.type === 'TSPropertySignature' && member.key.type === 'Identifier') {\n props.push({\n name: member.key.name,\n type: member.typeAnnotation\n ? this.typeToString(member.typeAnnotation.typeAnnotation)\n : 'unknown',\n isOptional: member.optional || false,\n isReadonly: member.readonly || false,\n });\n }\n }\n\n return props;\n }\n\n // ==========================================================================\n // Import Extraction\n // ==========================================================================\n\n private extractImports(ast: TSESTree.Program): ImportDef[] {\n const imports: ImportDef[] = [];\n\n for (const node of ast.body) {\n if (node.type === 'ImportDeclaration') {\n const source = node.source.value as string;\n const isRelative = source.startsWith('.') || source.startsWith('/');\n\n let defaultImport: string | undefined;\n let namedImports: string[] | undefined;\n let namespaceImport: string | undefined;\n\n for (const spec of node.specifiers || []) {\n if (spec.type === 'ImportDefaultSpecifier') {\n defaultImport = spec.local.name;\n } else if (spec.type === 'ImportSpecifier') {\n namedImports = namedImports || [];\n namedImports.push(spec.local.name);\n } else if (spec.type === 'ImportNamespaceSpecifier') {\n namespaceImport = spec.local.name;\n }\n }\n\n imports.push({\n source,\n isRelative,\n isTypeOnly: node.importKind === 'type',\n defaultImport,\n namedImports,\n namespaceImport,\n lineNumber: node.loc?.start.line || 0,\n });\n }\n }\n\n return imports;\n }\n\n // ==========================================================================\n // Comment Extraction\n // ==========================================================================\n\n private extractComments(comments: TSESTree.Comment[]): DocComment[] {\n const docComments: DocComment[] = [];\n\n for (const comment of comments) {\n // Only include JSDoc-style comments\n if (comment.type === 'Block' && comment.value.startsWith('*')) {\n const content = comment.value\n .split('\\n')\n .map((line) => line.replace(/^\\s*\\*\\s?/, ''))\n .join('\\n')\n .trim();\n\n const tags = this.extractDocTags(content);\n\n docComments.push({\n content,\n tags,\n lineStart: comment.loc?.start.line || 0,\n lineEnd: comment.loc?.end.line || 0,\n });\n }\n }\n\n return docComments;\n }\n\n private extractDocTags(content: string): DocComment['tags'] {\n const tags: DocComment['tags'] = [];\n const tagRegex = /@(\\w+)\\s*(?:\\{([^}]+)\\})?\\s*(?:(\\w+))?\\s*-?\\s*(.*)?/g;\n\n let match;\n while ((match = tagRegex.exec(content)) !== null) {\n tags.push({\n tag: match[1],\n type: match[2],\n name: match[3],\n description: match[4]?.trim(),\n });\n }\n\n return tags.length > 0 ? tags : undefined;\n }\n\n private findDocComment(\n comments: DocComment[],\n lineNumber: number\n ): string | undefined {\n // Find the closest comment that ends just before this line\n const closestComment = comments.find(\n (c) => c.lineEnd === lineNumber - 1 || c.lineEnd === lineNumber - 2\n );\n return closestComment?.content;\n }\n\n // ==========================================================================\n // Utility Methods\n // ==========================================================================\n\n private typeToString(typeNode: TSESTree.TypeNode): string {\n if (typeNode.type === 'TSStringKeyword') return 'string';\n if (typeNode.type === 'TSNumberKeyword') return 'number';\n if (typeNode.type === 'TSBooleanKeyword') return 'boolean';\n if (typeNode.type === 'TSAnyKeyword') return 'any';\n if (typeNode.type === 'TSVoidKeyword') return 'void';\n if (typeNode.type === 'TSNullKeyword') return 'null';\n if (typeNode.type === 'TSUndefinedKeyword') return 'undefined';\n if (typeNode.type === 'TSUnknownKeyword') return 'unknown';\n if (typeNode.type === 'TSNeverKeyword') return 'never';\n if (typeNode.type === 'TSTypeReference') {\n if (typeNode.typeName.type === 'Identifier') {\n return typeNode.typeName.name;\n }\n }\n if (typeNode.type === 'TSArrayType') {\n return `${this.typeToString(typeNode.elementType)}[]`;\n }\n if (typeNode.type === 'TSUnionType') {\n return typeNode.types.map((t) => this.typeToString(t)).join(' | ');\n }\n\n return 'unknown';\n }\n\n private nodeToString(node: TSESTree.Expression): string {\n if (node.type === 'Literal') {\n return JSON.stringify(node.value);\n }\n if (node.type === 'Identifier') {\n return node.name;\n }\n return 'complex';\n }\n\n private calculateComplexity(node: TSESTree.Node): number {\n let complexity = 1;\n\n const visit = (n: TSESTree.Node): void => {\n if (\n n.type === 'IfStatement' ||\n n.type === 'ConditionalExpression' ||\n n.type === 'ForStatement' ||\n n.type === 'ForInStatement' ||\n n.type === 'ForOfStatement' ||\n n.type === 'WhileStatement' ||\n n.type === 'DoWhileStatement' ||\n n.type === 'SwitchCase' ||\n n.type === 'CatchClause' ||\n n.type === 'LogicalExpression'\n ) {\n complexity++;\n }\n\n for (const key of Object.keys(n)) {\n const value = (n as Record<string, unknown>)[key];\n if (value && typeof value === 'object') {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as TSESTree.Node);\n }\n }\n } else if ('type' in value) {\n visit(value as TSESTree.Node);\n }\n }\n }\n };\n\n visit(node);\n return complexity;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet parserInstance: TypeScriptParser | null = null;\n\nexport function getTypeScriptParser(): TypeScriptParser {\n if (!parserInstance) {\n parserInstance = new TypeScriptParser();\n }\n return parserInstance;\n}\n","/**\n * Next.js Framework Extractor\n *\n * Extracts routes, middleware, and server actions from Next.js projects.\n * Supports both App Router and Pages Router patterns.\n */\n\nimport {\n CodeAST,\n FileMetadata,\n RouteDef,\n MiddlewareDef,\n ServerActionDef,\n FrameworkExtractor,\n Parameter,\n} from '../types.js';\n\n// ============================================================================\n// Next.js Extractor\n// ============================================================================\n\nexport class NextJSExtractor implements FrameworkExtractor {\n name = 'nextjs';\n\n /**\n * Check if this extractor can handle the file\n */\n canHandle(file: FileMetadata, content: string): boolean {\n // Check file path patterns\n const isAppRouter =\n file.path.includes('/app/') &&\n (file.path.endsWith('/route.ts') ||\n file.path.endsWith('/route.js') ||\n file.path.endsWith('/page.tsx') ||\n file.path.endsWith('/page.jsx'));\n\n const isPagesRouter =\n file.path.includes('/pages/api/') &&\n (file.path.endsWith('.ts') || file.path.endsWith('.js'));\n\n const isMiddleware =\n file.path.endsWith('/middleware.ts') ||\n file.path.endsWith('/middleware.js');\n\n // Check for server action directive\n const hasServerAction = content.includes(\"'use server'\") || content.includes('\"use server\"');\n\n return isAppRouter || isPagesRouter || isMiddleware || hasServerAction;\n }\n\n /**\n * Extract routes from the AST\n */\n extractRoutes(ast: CodeAST, content: string): RouteDef[] {\n const routes: RouteDef[] = [];\n\n if (ast.file.path.includes('/app/')) {\n // App Router\n routes.push(...this.extractAppRoutes(ast, content));\n } else if (ast.file.path.includes('/pages/api/')) {\n // Pages Router API routes\n routes.push(...this.extractPagesRoutes(ast, content));\n }\n\n return routes;\n }\n\n /**\n * Extract middleware definitions\n */\n extractMiddleware(ast: CodeAST, content: string): MiddlewareDef[] {\n if (!ast.file.path.endsWith('/middleware.ts') && !ast.file.path.endsWith('/middleware.js')) {\n return [];\n }\n\n const middlewareDefs: MiddlewareDef[] = [];\n\n // Look for the middleware function export\n const middlewareFunc = ast.functions.find(\n (f) => f.name === 'middleware' && f.isExported\n );\n\n if (middlewareFunc) {\n // Find config export for matcher\n const configConst = ast.constants.find(\n (c) => c.name === 'config' && c.isExported\n );\n\n let matcher: string | string[] | undefined;\n if (configConst?.value && typeof configConst.value === 'object') {\n const configValue = configConst.value as { matcher?: string | string[] };\n matcher = configValue.matcher;\n }\n\n middlewareDefs.push({\n name: 'middleware',\n matcher,\n docComment: middlewareFunc.docComment,\n lineNumber: middlewareFunc.lineStart,\n });\n }\n\n return middlewareDefs;\n }\n\n /**\n * Extract server actions\n */\n extractServerActions(ast: CodeAST, content: string): ServerActionDef[] {\n const actions: ServerActionDef[] = [];\n\n // Check for 'use server' directive\n if (!content.includes(\"'use server'\") && !content.includes('\"use server\"')) {\n return actions;\n }\n\n // In server action files, all exported async functions are actions\n for (const func of ast.functions) {\n if (func.isExported && func.isAsync) {\n actions.push({\n name: func.name,\n params: func.params,\n returnType: func.returnType,\n docComment: func.docComment,\n lineNumber: func.lineStart,\n });\n }\n }\n\n return actions;\n }\n\n // ==========================================================================\n // App Router Extraction\n // ==========================================================================\n\n private extractAppRoutes(ast: CodeAST, content: string): RouteDef[] {\n const routes: RouteDef[] = [];\n const path = this.pathFromAppRoute(ast.file.path);\n\n // HTTP method handlers in route.ts\n const httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];\n\n for (const method of httpMethods) {\n const handler = ast.functions.find(\n (f) => f.name === method && f.isExported\n );\n\n if (handler) {\n routes.push({\n method: method as RouteDef['method'],\n path,\n handler: method,\n handlerFile: ast.file.relativePath,\n params: this.extractRouteParams(path),\n requestBody: this.extractRequestBody(handler, content),\n responseType: this.extractResponseType(handler),\n docComment: handler.docComment,\n lineNumber: handler.lineStart,\n framework: 'nextjs',\n });\n }\n }\n\n return routes;\n }\n\n private pathFromAppRoute(filePath: string): string {\n // Convert /app/api/users/[id]/route.ts to /api/users/[id]\n const appIndex = filePath.indexOf('/app/');\n if (appIndex === -1) return '/';\n\n let path = filePath.substring(appIndex + 4); // Remove /app\n path = path.replace(/\\/route\\.(ts|js)$/, ''); // Remove route.ts/js\n path = path.replace(/\\/page\\.(tsx|jsx|ts|js)$/, ''); // Remove page.tsx/jsx\n\n // Convert [] params to :param format for documentation\n path = path.replace(/\\[\\.\\.\\.(\\w+)\\]/g, ':$1*'); // Catch-all\n path = path.replace(/\\[(\\w+)\\]/g, ':$1'); // Dynamic segment\n\n return path || '/';\n }\n\n // ==========================================================================\n // Pages Router Extraction\n // ==========================================================================\n\n private extractPagesRoutes(ast: CodeAST, content: string): RouteDef[] {\n const routes: RouteDef[] = [];\n const path = this.pathFromPagesRoute(ast.file.path);\n\n // Default export handler\n const defaultExport = ast.exports.find((e) => e.isDefault);\n if (!defaultExport) return routes;\n\n // Try to determine methods from the handler code\n const methods = this.detectMethodsFromContent(content);\n\n for (const method of methods) {\n routes.push({\n method,\n path,\n handler: 'default',\n handlerFile: ast.file.relativePath,\n params: this.extractRouteParams(path),\n framework: 'nextjs',\n lineNumber: defaultExport.lineNumber,\n });\n }\n\n return routes;\n }\n\n private pathFromPagesRoute(filePath: string): string {\n // Convert /pages/api/users/[id].ts to /api/users/[id]\n const pagesIndex = filePath.indexOf('/pages/');\n if (pagesIndex === -1) return '/api';\n\n let path = filePath.substring(pagesIndex + 6); // Remove /pages\n path = path.replace(/\\.(ts|js)$/, ''); // Remove extension\n path = path.replace(/\\/index$/, ''); // Remove /index\n\n // Convert [] params to :param format\n path = path.replace(/\\[\\.\\.\\.(\\w+)\\]/g, ':$1*');\n path = path.replace(/\\[(\\w+)\\]/g, ':$1');\n\n return path || '/api';\n }\n\n private detectMethodsFromContent(content: string): RouteDef['method'][] {\n const methods: RouteDef['method'][] = [];\n\n // Check for explicit method handling\n if (content.includes(\"req.method === 'GET'\") || content.includes('req.method === \"GET\"')) {\n methods.push('GET');\n }\n if (content.includes(\"req.method === 'POST'\") || content.includes('req.method === \"POST\"')) {\n methods.push('POST');\n }\n if (content.includes(\"req.method === 'PUT'\") || content.includes('req.method === \"PUT\"')) {\n methods.push('PUT');\n }\n if (content.includes(\"req.method === 'DELETE'\") || content.includes('req.method === \"DELETE\"')) {\n methods.push('DELETE');\n }\n if (content.includes(\"req.method === 'PATCH'\") || content.includes('req.method === \"PATCH\"')) {\n methods.push('PATCH');\n }\n\n // If no specific methods found, assume all\n if (methods.length === 0) {\n methods.push('ALL');\n }\n\n return methods;\n }\n\n // ==========================================================================\n // Helper Methods\n // ==========================================================================\n\n private extractRouteParams(path: string): RouteDef['params'] {\n const params: RouteDef['params'] = [];\n const paramRegex = /:(\\w+)(\\*)?/g;\n\n let match;\n while ((match = paramRegex.exec(path)) !== null) {\n params.push({\n name: match[1],\n type: 'string',\n required: true,\n description: match[2] ? 'Catch-all parameter' : 'Route parameter',\n });\n }\n\n return params.length > 0 ? params : undefined;\n }\n\n private extractRequestBody(\n handler: { params: Parameter[] },\n content: string\n ): RouteDef['requestBody'] {\n // Look for request body parsing patterns\n if (content.includes('.json()')) {\n // Try to find type annotation\n const jsonTypeMatch = content.match(/await\\s+\\w+\\.json\\(\\)\\s*(?:as\\s+(\\w+))?/);\n if (jsonTypeMatch?.[1]) {\n return {\n name: jsonTypeMatch[1],\n isArray: false,\n };\n }\n return {\n name: 'unknown',\n isArray: false,\n };\n }\n\n return undefined;\n }\n\n private extractResponseType(handler: { returnType?: string }): RouteDef['responseType'] {\n if (handler.returnType) {\n const responseMatch = handler.returnType.match(/(?:Promise<)?Response|NextResponse/);\n if (responseMatch) {\n return {\n name: 'Response',\n isArray: false,\n };\n }\n }\n return undefined;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet extractorInstance: NextJSExtractor | null = null;\n\nexport function getNextJSExtractor(): NextJSExtractor {\n if (!extractorInstance) {\n extractorInstance = new NextJSExtractor();\n }\n return extractorInstance;\n}\n","/**\n * Express.js Framework Extractor\n *\n * Extracts routes and middleware from Express.js projects.\n * Supports common patterns like app.get(), router.post(), etc.\n */\n\nimport {\n CodeAST,\n FileMetadata,\n RouteDef,\n MiddlewareDef,\n FrameworkExtractor,\n} from '../types.js';\n\n// ============================================================================\n// Express Extractor\n// ============================================================================\n\nexport class ExpressExtractor implements FrameworkExtractor {\n name = 'express';\n\n /**\n * Check if this extractor can handle the file\n */\n canHandle(file: FileMetadata, content: string): boolean {\n // Check for Express imports\n const hasExpressImport =\n content.includes(\"from 'express'\") ||\n content.includes('from \"express\"') ||\n content.includes(\"require('express')\") ||\n content.includes('require(\"express\")');\n\n // Check for Router usage\n const hasRouterUsage =\n content.includes('express.Router()') ||\n content.includes('Router()') ||\n content.includes('app.get(') ||\n content.includes('app.post(') ||\n content.includes('router.get(') ||\n content.includes('router.post(');\n\n return hasExpressImport || hasRouterUsage;\n }\n\n /**\n * Extract routes from the content using regex patterns\n */\n extractRoutes(ast: CodeAST, content: string): RouteDef[] {\n const routes: RouteDef[] = [];\n\n // Match patterns like: app.get('/path', handler) or router.post('/path', middleware, handler)\n const routePatterns = [\n // app.method('path', ...)\n /(?:app|router)\\.(get|post|put|delete|patch|head|options|all)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/gi,\n // Router().method('path', ...)\n /Router\\(\\)\\.(get|post|put|delete|patch|head|options|all)\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/gi,\n ];\n\n for (const pattern of routePatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const method = match[1].toUpperCase() as RouteDef['method'];\n const path = match[2];\n const lineNumber = this.getLineNumber(content, match.index);\n\n // Extract middleware and handler names\n const { middleware, handler } = this.extractHandlerInfo(content, match.index);\n\n routes.push({\n method,\n path,\n handler: handler || 'anonymous',\n handlerFile: ast.file.relativePath,\n middleware,\n params: this.extractRouteParams(path),\n lineNumber,\n framework: 'express',\n });\n }\n }\n\n return routes;\n }\n\n /**\n * Extract middleware definitions\n */\n extractMiddleware(ast: CodeAST, content: string): MiddlewareDef[] {\n const middlewareDefs: MiddlewareDef[] = [];\n\n // Match app.use() patterns\n const usePattern = /(?:app|router)\\.use\\s*\\(\\s*(?:['\"`]([^'\"`]*)['\"`]\\s*,\\s*)?(\\w+)/g;\n\n let match;\n while ((match = usePattern.exec(content)) !== null) {\n const path = match[1];\n const middlewareName = match[2];\n const lineNumber = this.getLineNumber(content, match.index);\n\n middlewareDefs.push({\n name: middlewareName,\n matcher: path,\n lineNumber,\n });\n }\n\n // Also find middleware functions defined with common patterns\n for (const func of ast.functions) {\n // Check for middleware signature: (req, res, next) => ...\n if (\n func.params.length === 3 &&\n func.params.some((p) => p.name === 'req' || p.name === 'request') &&\n func.params.some((p) => p.name === 'res' || p.name === 'response') &&\n func.params.some((p) => p.name === 'next')\n ) {\n middlewareDefs.push({\n name: func.name,\n docComment: func.docComment,\n lineNumber: func.lineStart,\n });\n }\n }\n\n return middlewareDefs;\n }\n\n // ==========================================================================\n // Helper Methods\n // ==========================================================================\n\n private extractRouteParams(path: string): RouteDef['params'] {\n const params: RouteDef['params'] = [];\n const paramRegex = /:(\\w+)(\\?)?/g;\n\n let match;\n while ((match = paramRegex.exec(path)) !== null) {\n params.push({\n name: match[1],\n type: 'string',\n required: !match[2], // ? makes it optional\n description: 'Route parameter',\n });\n }\n\n return params.length > 0 ? params : undefined;\n }\n\n private extractHandlerInfo(\n content: string,\n routeIndex: number\n ): { middleware?: string[]; handler?: string } {\n // Find the full route definition\n const searchStart = content.indexOf('(', routeIndex);\n if (searchStart === -1) return {};\n\n // Find matching closing parenthesis\n let depth = 1;\n let i = searchStart + 1;\n let argStart = i;\n const args: string[] = [];\n\n // Skip the path argument (first string)\n while (i < content.length && depth > 0) {\n const char = content[i];\n if (char === '(') depth++;\n else if (char === ')') depth--;\n else if (char === ',' && depth === 1) {\n const arg = content.substring(argStart, i).trim();\n if (arg && !arg.startsWith(\"'\") && !arg.startsWith('\"') && !arg.startsWith('`')) {\n args.push(arg);\n }\n argStart = i + 1;\n }\n i++;\n }\n\n // Get last argument\n const lastArg = content.substring(argStart, i - 1).trim();\n if (lastArg && !lastArg.startsWith(\"'\") && !lastArg.startsWith('\"') && !lastArg.startsWith('`')) {\n args.push(lastArg);\n }\n\n if (args.length === 0) return {};\n if (args.length === 1) return { handler: this.extractFunctionName(args[0]) };\n\n // Last arg is handler, rest are middleware\n return {\n middleware: args.slice(0, -1).map((a) => this.extractFunctionName(a)),\n handler: this.extractFunctionName(args[args.length - 1]),\n };\n }\n\n private extractFunctionName(arg: string): string {\n // Handle inline functions\n if (arg.includes('=>') || arg.includes('function')) {\n return 'anonymous';\n }\n // Handle function calls like auth()\n const callMatch = arg.match(/^(\\w+)\\s*\\(/);\n if (callMatch) return callMatch[1];\n // Plain identifier\n const identMatch = arg.match(/^\\w+$/);\n if (identMatch) return arg;\n return 'anonymous';\n }\n\n private getLineNumber(content: string, index: number): number {\n return content.substring(0, index).split('\\n').length;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet extractorInstance: ExpressExtractor | null = null;\n\nexport function getExpressExtractor(): ExpressExtractor {\n if (!extractorInstance) {\n extractorInstance = new ExpressExtractor();\n }\n return extractorInstance;\n}\n","/**\n * AST Module\n *\n * Provides structured code analysis for improved verification accuracy.\n * Reduces token usage by converting raw code to compact AST format.\n */\n\n// Types\nexport * from './types.js';\n\n// TypeScript Parser\nexport { TypeScriptParser, getTypeScriptParser } from './typescript-parser.js';\n\n// Framework Extractors\nexport { NextJSExtractor, getNextJSExtractor } from './extractors/nextjs.js';\nexport { ExpressExtractor, getExpressExtractor } from './extractors/express.js';\n\nimport { CodeAST, FileMetadata, FrameworkExtractor, ASTSummary } from './types.js';\nimport { getTypeScriptParser } from './typescript-parser.js';\nimport { getNextJSExtractor } from './extractors/nextjs.js';\nimport { getExpressExtractor } from './extractors/express.js';\n\n// ============================================================================\n// AST Service\n// ============================================================================\n\n/**\n * Parse a file and extract structured AST with framework-specific routes\n */\nexport async function parseFile(\n content: string,\n metadata: FileMetadata\n): Promise<CodeAST> {\n const parser = getTypeScriptParser();\n\n // Parse the file\n let ast: CodeAST;\n try {\n ast = parser.parse(content, metadata);\n } catch (err) {\n // Return empty AST on parse error\n console.warn(`Failed to parse ${metadata.path}:`, err);\n return {\n file: metadata,\n exports: [],\n functions: [],\n classes: [],\n routes: [],\n constants: [],\n types: [],\n docComments: [],\n imports: [],\n };\n }\n\n // Apply framework extractors\n const extractors: FrameworkExtractor[] = [\n getNextJSExtractor(),\n getExpressExtractor(),\n ];\n\n for (const extractor of extractors) {\n if (extractor.canHandle(metadata, content)) {\n ast.file.framework = extractor.name;\n\n // Extract routes\n const routes = extractor.extractRoutes(ast, content);\n ast.routes.push(...routes);\n\n // Extract middleware if supported\n if (extractor.extractMiddleware) {\n // Middleware is returned but stored separately if needed\n extractor.extractMiddleware(ast, content);\n }\n\n break; // Only use first matching extractor\n }\n }\n\n return ast;\n}\n\n/**\n * Parse multiple files and generate summaries\n */\nexport async function parseFiles(\n files: Array<{ content: string; metadata: FileMetadata }>\n): Promise<CodeAST[]> {\n const results: CodeAST[] = [];\n\n for (const file of files) {\n const ast = await parseFile(file.content, file.metadata);\n results.push(ast);\n }\n\n return results;\n}\n\n/**\n * Generate a compact summary for AI consumption\n */\nexport function summarizeAST(ast: CodeAST): ASTSummary {\n const parser = getTypeScriptParser();\n return parser.summarize(ast);\n}\n\n/**\n * Generate a compact representation for AI prompts\n * Significantly reduces token usage vs raw code\n * INCLUDES LINE NUMBERS for accurate file:line references\n */\nexport function astToPromptFormat(ast: CodeAST): string {\n const lines: string[] = [];\n const file = ast.file.relativePath;\n\n lines.push(`# ${file}`);\n lines.push(`Language: ${ast.file.language}${ast.file.framework ? ` (${ast.file.framework})` : ''}`);\n lines.push('');\n\n // Routes (most important for API verification) - WITH LINE NUMBERS\n if (ast.routes.length > 0) {\n lines.push('## Routes');\n for (const route of ast.routes) {\n lines.push(`- ${route.method} ${route.path} [L${route.lineNumber}]`);\n if (route.params) {\n lines.push(` Params: ${route.params.map((p) => `${p.name}${p.required ? '' : '?'}`).join(', ')}`);\n }\n if (route.requestBody) {\n lines.push(` Body: ${route.requestBody.name}`);\n }\n if (route.middleware && route.middleware.length > 0) {\n lines.push(` Middleware: ${route.middleware.join(' -> ')}`);\n }\n }\n lines.push('');\n }\n\n // Exported functions - WITH LINE NUMBERS\n const exportedFuncs = ast.functions.filter((f) => f.isExported);\n if (exportedFuncs.length > 0) {\n lines.push('## Exported Functions');\n for (const func of exportedFuncs) {\n const params = func.params.map((p) => `${p.name}${p.isOptional ? '?' : ''}: ${p.type || 'any'}`);\n const lineRange = func.lineEnd > func.lineStart\n ? `[L${func.lineStart}-${func.lineEnd}]`\n : `[L${func.lineStart}]`;\n lines.push(`- ${func.isAsync ? 'async ' : ''}${func.name}(${params.join(', ')}): ${func.returnType || 'void'} ${lineRange}`);\n if (func.docComment) {\n lines.push(` /** ${func.docComment.split('\\n')[0]} */`);\n }\n }\n lines.push('');\n }\n\n // Exported types - WITH LINE NUMBERS\n const exportedTypes = ast.types.filter((t) => t.isExported);\n if (exportedTypes.length > 0) {\n lines.push('## Types');\n for (const type of exportedTypes) {\n const lineRange = type.lineEnd > type.lineStart\n ? `[L${type.lineStart}-${type.lineEnd}]`\n : `[L${type.lineStart}]`;\n if (type.kind === 'interface' && type.properties) {\n lines.push(`- interface ${type.name} ${lineRange} {`);\n for (const prop of type.properties.slice(0, 10)) { // Limit properties\n lines.push(` ${prop.name}${prop.isOptional ? '?' : ''}: ${prop.type}`);\n }\n if (type.properties.length > 10) {\n lines.push(` ... ${type.properties.length - 10} more`);\n }\n lines.push(' }');\n } else if (type.kind === 'enum' && type.enumValues) {\n lines.push(`- enum ${type.name} ${lineRange} { ${type.enumValues.map((v) => v.name).join(', ')} }`);\n } else {\n lines.push(`- type ${type.name} ${lineRange}`);\n }\n }\n lines.push('');\n }\n\n // Config constants - WITH LINE NUMBERS\n const configConstants = ast.constants.filter(\n (c) => c.category === 'config' || c.category === 'limit'\n );\n if (configConstants.length > 0) {\n lines.push('## Constants');\n for (const constant of configConstants) {\n lines.push(`- ${constant.name}: ${JSON.stringify(constant.value)} [L${constant.lineNumber}]`);\n }\n lines.push('');\n }\n\n // Classes - WITH LINE NUMBERS\n if (ast.classes.length > 0) {\n lines.push('## Classes');\n for (const cls of ast.classes) {\n const lineRange = cls.lineEnd > cls.lineStart\n ? `[L${cls.lineStart}-${cls.lineEnd}]`\n : `[L${cls.lineStart}]`;\n lines.push(`- class ${cls.name}${cls.extends ? ` extends ${cls.extends}` : ''} ${lineRange}`);\n const publicMethods = cls.methods.filter((m) => m.visibility === 'public');\n for (const method of publicMethods.slice(0, 5)) {\n const methodRange = method.lineEnd > method.lineStart\n ? `[L${method.lineStart}-${method.lineEnd}]`\n : `[L${method.lineStart}]`;\n lines.push(` ${method.name}() ${methodRange}`);\n }\n if (publicMethods.length > 5) {\n lines.push(` ... ${publicMethods.length - 5} more methods`);\n }\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Calculate token savings from using AST vs raw code\n */\nexport function calculateTokenSavings(\n rawCodeLength: number,\n astPromptLength: number\n): { savings: number; percentage: number } {\n // Rough estimate: 4 chars per token\n const rawTokens = Math.ceil(rawCodeLength / 4);\n const astTokens = Math.ceil(astPromptLength / 4);\n const savings = rawTokens - astTokens;\n const percentage = Math.round((savings / rawTokens) * 100);\n\n return { savings, percentage };\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, jsonResult, errorResult } from './types.js';\nimport { createJsonCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { parseFile, astToPromptFormat, type CodeAST, type FileMetadata } from '../ast/index.js';\nimport { existsSync, readFileSync, statSync, readdirSync } from 'fs';\nimport { resolve, relative, extname, join } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface EnhancedValidationResult {\n summary: {\n overallScore: number;\n verdict: 'pass' | 'pass_with_concerns' | 'fail';\n criticalIssues: number;\n totalRequirements: number;\n coveredRequirements: number;\n };\n requirements: ValidatedRequirement[];\n gaps: GapAnalysis[];\n recommendations: Recommendation[];\n astSummary?: {\n totalFiles: number;\n totalFunctions: number;\n totalRoutes: number;\n totalTypes: number;\n };\n tokensUsed: number;\n}\n\ninterface ValidatedRequirement {\n id: string;\n description: string;\n status: 'met' | 'partial' | 'not_met' | 'cannot_verify';\n confidence: number;\n evidence: {\n filePath?: string;\n lineNumber?: number;\n lineRange?: { start: number; end: number };\n codeSnippet?: string;\n explanation: string;\n }[];\n missingElements?: string[];\n}\n\ninterface GapAnalysis {\n type: 'unimplemented' | 'partial' | 'deviation' | 'over_engineering';\n severity: 'critical' | 'high' | 'medium' | 'low';\n requirement?: string;\n description: string;\n filePath?: string;\n lineNumber?: number;\n recommendation: string;\n}\n\ninterface Recommendation {\n priority: number;\n category: 'functional' | 'edge_cases' | 'error_handling' | 'performance' | 'security' | 'accessibility' | 'ux';\n issue: string;\n filePath?: string;\n lineNumber?: number;\n suggestedFix?: string;\n estimatedEffort: 'trivial' | 'small' | 'medium' | 'large';\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Discover and read code files from a repository path\n */\nasync function discoverCodeFiles(\n repoPath: string,\n codeFiles?: string[]\n): Promise<Array<{ path: string; relativePath: string; content: string; language: string }>> {\n const resolvedPath = resolve(repoPath);\n const files: Array<{ path: string; relativePath: string; content: string; language: string }> = [];\n\n // If specific files are provided, use them\n if (codeFiles && codeFiles.length > 0) {\n for (const filePath of codeFiles) {\n const fullPath = resolve(repoPath, filePath);\n if (existsSync(fullPath)) {\n const stat = statSync(fullPath);\n if (stat.isFile() && stat.size < 512 * 1024) { // Max 512KB\n const content = readFileSync(fullPath, 'utf-8');\n const ext = extname(fullPath);\n const language = getLanguageFromExtension(ext);\n if (language) {\n files.push({\n path: fullPath,\n relativePath: relative(resolvedPath, fullPath),\n content,\n language,\n });\n }\n }\n }\n }\n return files;\n }\n\n // Use native fs.readdirSync with recursive option to find code files\n const supportedExtensions = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.go']);\n const ignoreDirs = new Set(['node_modules', 'dist', 'build', '.next', 'coverage', '__tests__', '.git']);\n\n try {\n const entries = readdirSync(resolvedPath, { withFileTypes: true, recursive: true });\n let fileCount = 0;\n const maxFiles = 50;\n\n for (const entry of entries) {\n if (fileCount >= maxFiles) break;\n\n // Skip if not a file\n if (!entry.isFile()) continue;\n\n // Get full path\n const fullPath = entry.parentPath\n ? join(entry.parentPath, entry.name)\n : join(resolvedPath, entry.name);\n const relativePath = relative(resolvedPath, fullPath);\n\n // Skip ignored directories\n const pathParts = relativePath.split('/');\n if (pathParts.some(part => ignoreDirs.has(part))) continue;\n\n // Skip test files\n if (entry.name.includes('.test.') || entry.name.includes('.spec.')) continue;\n\n // Check extension\n const ext = extname(entry.name);\n if (!supportedExtensions.has(ext)) continue;\n\n // Check file size\n try {\n const stat = statSync(fullPath);\n if (stat.size >= 512 * 1024) continue; // Skip files > 512KB\n\n const content = readFileSync(fullPath, 'utf-8');\n const language = getLanguageFromExtension(ext);\n if (language) {\n files.push({\n path: fullPath,\n relativePath,\n content,\n language,\n });\n fileCount++;\n }\n } catch {\n // Skip files that can't be read\n }\n }\n } catch {\n // Ignore directory read errors\n }\n\n return files;\n}\n\nfunction getLanguageFromExtension(ext: string): string | null {\n const map: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.py': 'python',\n '.go': 'go',\n '.java': 'java',\n '.rs': 'rust',\n };\n return map[ext] || null;\n}\n\n/**\n * Parse code files to AST and generate compact representations\n */\nasync function parseCodeToAST(\n files: Array<{ path: string; relativePath: string; content: string; language: string }>\n): Promise<{ asts: CodeAST[]; promptFormat: string }> {\n const asts: CodeAST[] = [];\n const prompts: string[] = [];\n\n for (const file of files) {\n if (file.language !== 'typescript' && file.language !== 'javascript') {\n // For non-TS/JS files, just include raw content (truncated)\n prompts.push(`# ${file.relativePath}\\n\\`\\`\\`${file.language}\\n${file.content.substring(0, 5000)}\\n\\`\\`\\``);\n continue;\n }\n\n const metadata: FileMetadata = {\n path: file.path,\n relativePath: file.relativePath,\n language: file.language as 'typescript' | 'javascript',\n size: file.content.length,\n };\n\n try {\n const ast = await parseFile(file.content, metadata);\n asts.push(ast);\n prompts.push(astToPromptFormat(ast));\n } catch {\n // Fallback to raw content if parsing fails\n prompts.push(`# ${file.relativePath}\\n\\`\\`\\`${file.language}\\n${file.content.substring(0, 3000)}\\n\\`\\`\\``);\n }\n }\n\n return { asts, promptFormat: prompts.join('\\n\\n') };\n}\n\n/**\n * Build context for finding specific code locations\n */\nfunction buildCodeLocationMap(\n asts: CodeAST[]\n): Map<string, { file: string; line: number }> {\n const map = new Map<string, { file: string; line: number }>();\n\n for (const ast of asts) {\n // Map functions\n for (const func of ast.functions) {\n map.set(`func:${func.name}`, { file: ast.file.relativePath, line: func.lineStart });\n }\n\n // Map routes\n for (const route of ast.routes) {\n map.set(`route:${route.method}:${route.path}`, { file: ast.file.relativePath, line: route.lineNumber });\n }\n\n // Map types\n for (const type of ast.types) {\n map.set(`type:${type.name}`, { file: ast.file.relativePath, line: type.lineStart });\n }\n\n // Map classes\n for (const cls of ast.classes) {\n map.set(`class:${cls.name}`, { file: ast.file.relativePath, line: cls.lineStart });\n for (const method of cls.methods) {\n map.set(`method:${cls.name}.${method.name}`, { file: ast.file.relativePath, line: method.lineStart });\n }\n }\n\n // Map constants\n for (const constant of ast.constants) {\n map.set(`const:${constant.name}`, { file: ast.file.relativePath, line: constant.lineNumber });\n }\n }\n\n return map;\n}\n\n// ============================================================================\n// Main Tool Definition\n// ============================================================================\n\n/**\n * validate_implementation tool - Check code against requirements\n */\nexport const validateImplementationTool: ToolDefinition = {\n tool: {\n name: 'validate_implementation',\n description: `Validate that code implementation matches requirements.\n\nCompares source code against PRD/requirements and produces:\n- Requirements coverage report with specific file:line references\n- Gap analysis with actionable recommendations\n- AST-based verification for accurate code location\n- Acceptance criteria verification\n\nSupports two modes:\n1. **File mode** (recommended): Provide repoPath to read actual files\n2. **Snippet mode**: Provide code string directly\n\nBest for: Pre-release validation and QA support.`,\n inputSchema: {\n type: 'object',\n properties: {\n requirements: {\n type: 'string',\n description: 'PRD, user stories, or requirements to validate against',\n },\n repoPath: {\n type: 'string',\n description: 'Path to repository for file-based validation (reads actual files)',\n },\n codeFiles: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific code files to validate (relative to repoPath). Auto-discovers if not specified.',\n },\n code: {\n type: 'string',\n description: 'Implementation code snippet (alternative to repoPath)',\n },\n strictness: {\n type: 'string',\n enum: ['lenient', 'standard', 'strict'],\n default: 'standard',\n description: 'How strictly to validate',\n },\n checkTypes: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'functional',\n 'edge_cases',\n 'error_handling',\n 'performance',\n 'security',\n 'accessibility',\n 'ux',\n ],\n },\n default: ['functional', 'edge_cases', 'error_handling'],\n description: 'Types of validation to perform',\n },\n outputFormat: {\n type: 'string',\n enum: ['markdown', 'json'],\n default: 'markdown',\n description: 'Output format for the validation report',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to repoPath or current directory)',\n },\n },\n required: ['requirements'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const requirements = args.requirements as string;\n const repoPath = args.repoPath as string | undefined;\n const codeFiles = args.codeFiles as string[] | undefined;\n const codeSnippet = args.code as string | undefined;\n const strictness = (args.strictness as string) || 'standard';\n const checkTypes = (args.checkTypes as string[]) || ['functional', 'edge_cases', 'error_handling'];\n const outputFormat = (args.outputFormat as string) || 'markdown';\n const projectRoot = (args.projectRoot as string) || repoPath || process.cwd();\n\n if (!requirements || requirements.trim().length === 0) {\n return errorResult('Requirements are required for validation');\n }\n\n // Determine code source\n let codeContent: string;\n let asts: CodeAST[] = [];\n let astSummary: EnhancedValidationResult['astSummary'] | undefined;\n\n if (repoPath) {\n // File-based validation mode\n const resolvedPath = resolve(repoPath);\n if (!existsSync(resolvedPath)) {\n return errorResult(`Repository path does not exist: ${resolvedPath}`);\n }\n\n try {\n const files = await discoverCodeFiles(resolvedPath, codeFiles);\n if (files.length === 0) {\n return errorResult('No code files found in repository. Provide codeFiles or ensure code exists.');\n }\n\n const parsed = await parseCodeToAST(files);\n asts = parsed.asts;\n codeContent = parsed.promptFormat;\n\n // Calculate AST summary\n astSummary = {\n totalFiles: asts.length,\n totalFunctions: asts.reduce((sum, ast) => sum + ast.functions.length, 0),\n totalRoutes: asts.reduce((sum, ast) => sum + ast.routes.length, 0),\n totalTypes: asts.reduce((sum, ast) => sum + ast.types.length, 0),\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n return errorResult(`Failed to read code files: ${message}`);\n }\n } else if (codeSnippet) {\n // Snippet mode\n codeContent = codeSnippet;\n } else {\n return errorResult('Either repoPath or code is required for validation');\n }\n\n // Build code location map for potential future use (e.g., enhancing prompts)\n // Note: locationMap contains func/route/type/class locations from AST\n buildCodeLocationMap(asts);\n\n const strictnessGuide: Record<string, string> = {\n lenient: 'Accept reasonable interpretations. Flag only clear deviations.',\n standard: 'Check for requirement coverage and edge cases. Flag gaps and concerns.',\n strict: 'Exact requirement matching. Every stated requirement must be verifiably implemented.',\n };\n\n const systemPrompt = `You are a QA lead expert at validating implementations against requirements.\n${repoPath ? 'You are analyzing ACTUAL code files with AST-extracted structure INCLUDING EXACT LINE NUMBERS.' : 'You are analyzing a code snippet.'}\n\nStrictness: ${strictnessGuide[strictness]}\nValidation Types: ${checkTypes.join(', ')}\n\nCRITICAL: The code has been parsed with line numbers in [L##] format. USE THESE EXACT LINE NUMBERS in your evidence!\n- File path where it's implemented (e.g., \"src/auth/login.ts\")\n- Line numbers FROM THE AST (e.g., if you see \"createUser [L42-67]\" use lines 42-67)\n- Code snippet quotes showing the implementation\n\nLine number format in the AST:\n- [L15] = single line 15\n- [L15-45] = lines 15 through 45\nAlways use these AST-provided line numbers, not guesses!\n\nOutput a JSON object with this structure:\n{\n \"summary\": {\n \"overallScore\": 85,\n \"verdict\": \"pass_with_concerns\",\n \"criticalIssues\": 1,\n \"totalRequirements\": 10,\n \"coveredRequirements\": 8\n },\n \"requirements\": [\n {\n \"id\": \"REQ-001\",\n \"description\": \"User authentication with JWT\",\n \"status\": \"met\",\n \"confidence\": 95,\n \"evidence\": [\n {\n \"filePath\": \"src/auth/jwt.ts\",\n \"lineNumber\": 15,\n \"lineRange\": { \"start\": 15, \"end\": 45 },\n \"codeSnippet\": \"export function generateToken(...)\",\n \"explanation\": \"JWT generation implemented with proper expiration\"\n }\n ],\n \"missingElements\": []\n },\n {\n \"id\": \"REQ-002\",\n \"description\": \"Rate limiting at 100 req/min\",\n \"status\": \"partial\",\n \"confidence\": 70,\n \"evidence\": [\n {\n \"filePath\": \"src/middleware/rate-limit.ts\",\n \"lineNumber\": 23,\n \"explanation\": \"Rate limiting exists but uses 50/min not 100/min\"\n }\n ],\n \"missingElements\": [\"Documented limit of 100/min not implemented\"]\n }\n ],\n \"gaps\": [\n {\n \"type\": \"deviation\",\n \"severity\": \"high\",\n \"requirement\": \"REQ-002\",\n \"description\": \"Rate limit mismatch: docs say 100/min, code has 50/min\",\n \"filePath\": \"src/middleware/rate-limit.ts\",\n \"lineNumber\": 23,\n \"recommendation\": \"Update RATE_LIMIT constant from 50 to 100\"\n }\n ],\n \"recommendations\": [\n {\n \"priority\": 1,\n \"category\": \"functional\",\n \"issue\": \"Rate limit doesn't match documentation\",\n \"filePath\": \"src/middleware/rate-limit.ts\",\n \"lineNumber\": 23,\n \"suggestedFix\": \"Change RATE_LIMIT from 50 to 100\",\n \"estimatedEffort\": \"trivial\"\n }\n ]\n}`;\n\n // Truncate inputs if needed\n const reqTrunc = requirements.length > 12000\n ? requirements.substring(0, 12000) + '\\n... [truncated]'\n : requirements;\n const codeTrunc = codeContent.length > 30000\n ? codeContent.substring(0, 30000) + '\\n// ... [truncated]'\n : codeContent;\n\n const userMessage = `Validate this implementation against the requirements:\n\n## Requirements\n${reqTrunc}\n\n## Implementation Code${astSummary ? ` (${astSummary.totalFiles} files, ${astSummary.totalFunctions} functions, ${astSummary.totalRoutes} routes)` : ''}\n${codeTrunc}\n\nProduce a comprehensive validation report with specific file:line references for EVERY finding.`;\n\n try {\n const result = await createJsonCompletion<EnhancedValidationResult>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 8192,\n });\n\n const validationResult = result.data;\n validationResult.tokensUsed = result.inputTokens + result.outputTokens;\n if (astSummary) {\n validationResult.astSummary = astSummary;\n }\n\n // Format output\n let output: string;\n if (outputFormat === 'json') {\n output = JSON.stringify(validationResult, null, 2);\n } else {\n output = formatValidationReport(validationResult, repoPath);\n }\n\n // Auto-save output\n const defaults = getToolDefaults('validate_implementation');\n const saved = saveToolOutput({\n projectRoot: resolve(projectRoot),\n toolName: 'validate_implementation',\n category: defaults.category,\n filename: defaults.filename,\n content: output,\n format: outputFormat === 'json' ? 'json' : 'md',\n inputs: checkTypes,\n tokensUsed: validationResult.tokensUsed,\n });\n\n if (outputFormat === 'json') {\n return jsonResult(validationResult, validationResult.tokensUsed);\n }\n\n return markdownResult(output + formatSavedPath(saved), validationResult.tokensUsed);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to validate implementation: ${message}`);\n }\n },\n\n requiredScope: 'tools:validate_implementation',\n};\n\n// ============================================================================\n// Formatting Functions\n// ============================================================================\n\nfunction formatValidationReport(result: EnhancedValidationResult, repoPath?: string): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# Implementation Validation Report');\n lines.push('');\n lines.push(`**Generated:** ${new Date().toISOString()}`);\n if (repoPath) {\n lines.push(`**Repository:** ${repoPath}`);\n }\n lines.push('');\n\n // Summary\n const verdictEmoji = {\n pass: '✅',\n pass_with_concerns: '⚠️',\n fail: '❌',\n };\n lines.push('## Summary');\n lines.push('');\n lines.push(`**Verdict:** ${verdictEmoji[result.summary.verdict]} ${result.summary.verdict.replace(/_/g, ' ').toUpperCase()}`);\n lines.push(`**Score:** ${result.summary.overallScore}/100`);\n lines.push(`**Coverage:** ${result.summary.coveredRequirements}/${result.summary.totalRequirements} requirements`);\n if (result.summary.criticalIssues > 0) {\n lines.push(`**Critical Issues:** 🚨 ${result.summary.criticalIssues}`);\n }\n lines.push('');\n\n // AST Summary (if available)\n if (result.astSummary) {\n lines.push('## Code Analysis');\n lines.push('');\n lines.push(`- **Files Analyzed:** ${result.astSummary.totalFiles}`);\n lines.push(`- **Functions Found:** ${result.astSummary.totalFunctions}`);\n lines.push(`- **Routes Found:** ${result.astSummary.totalRoutes}`);\n lines.push(`- **Types Found:** ${result.astSummary.totalTypes}`);\n lines.push('');\n }\n\n // Requirements Coverage Matrix\n lines.push('## Requirements Coverage');\n lines.push('');\n lines.push('| ID | Description | Status | Confidence | Location |');\n lines.push('|----|-------------|--------|------------|----------|');\n\n for (const req of result.requirements) {\n const statusEmoji = {\n met: '✅',\n partial: '⚠️',\n not_met: '❌',\n cannot_verify: '❓',\n };\n const location = req.evidence[0]\n ? req.evidence[0].filePath\n ? `${req.evidence[0].filePath}:${req.evidence[0].lineNumber || '?'}`\n : '-'\n : '-';\n const desc = req.description.length > 40\n ? req.description.substring(0, 40) + '...'\n : req.description;\n lines.push(`| ${req.id} | ${desc} | ${statusEmoji[req.status]} ${req.status} | ${req.confidence}% | ${location} |`);\n }\n lines.push('');\n\n // Detailed findings for non-met requirements\n const issues = result.requirements.filter((r) => r.status !== 'met');\n if (issues.length > 0) {\n lines.push('## Issues Requiring Attention');\n lines.push('');\n\n for (const req of issues) {\n const severityEmoji = req.status === 'not_met' ? '🔴' : '🟠';\n lines.push(`### ${severityEmoji} ${req.id}: ${req.description}`);\n lines.push('');\n lines.push(`**Status:** ${req.status} (${req.confidence}% confidence)`);\n lines.push('');\n\n if (req.evidence.length > 0) {\n lines.push('**Evidence:**');\n for (const ev of req.evidence) {\n if (ev.filePath) {\n const loc = ev.lineRange\n ? `${ev.filePath}:${ev.lineRange.start}-${ev.lineRange.end}`\n : ev.lineNumber\n ? `${ev.filePath}:${ev.lineNumber}`\n : ev.filePath;\n lines.push(`- \\`${loc}\\``);\n }\n lines.push(` ${ev.explanation}`);\n if (ev.codeSnippet) {\n lines.push(` \\`\\`\\`\\n ${ev.codeSnippet.substring(0, 200)}\\n \\`\\`\\``);\n }\n }\n lines.push('');\n }\n\n if (req.missingElements && req.missingElements.length > 0) {\n lines.push('**Missing:**');\n for (const missing of req.missingElements) {\n lines.push(`- ${missing}`);\n }\n lines.push('');\n }\n }\n }\n\n // Gaps & Deviations\n if (result.gaps.length > 0) {\n lines.push('## Gaps & Deviations');\n lines.push('');\n\n const criticalGaps = result.gaps.filter((g) => g.severity === 'critical');\n const highGaps = result.gaps.filter((g) => g.severity === 'high');\n const otherGaps = result.gaps.filter((g) => g.severity !== 'critical' && g.severity !== 'high');\n\n if (criticalGaps.length > 0) {\n lines.push('### 🚨 Critical');\n for (const gap of criticalGaps) {\n const loc = gap.filePath ? `\\`${gap.filePath}:${gap.lineNumber || '?'}\\`` : '';\n lines.push(`- **${gap.type}**: ${gap.description} ${loc}`);\n lines.push(` - *Recommendation:* ${gap.recommendation}`);\n }\n lines.push('');\n }\n\n if (highGaps.length > 0) {\n lines.push('### 🔴 High Priority');\n for (const gap of highGaps) {\n const loc = gap.filePath ? `\\`${gap.filePath}:${gap.lineNumber || '?'}\\`` : '';\n lines.push(`- **${gap.type}**: ${gap.description} ${loc}`);\n lines.push(` - *Recommendation:* ${gap.recommendation}`);\n }\n lines.push('');\n }\n\n if (otherGaps.length > 0) {\n lines.push('### Other Issues');\n for (const gap of otherGaps) {\n const loc = gap.filePath ? `\\`${gap.filePath}:${gap.lineNumber || '?'}\\`` : '';\n lines.push(`- [${gap.severity}] ${gap.description} ${loc}`);\n }\n lines.push('');\n }\n }\n\n // Recommendations\n if (result.recommendations.length > 0) {\n lines.push('## Recommendations');\n lines.push('');\n lines.push('| Priority | Category | Issue | Location | Effort |');\n lines.push('|----------|----------|-------|----------|--------|');\n\n for (const rec of result.recommendations.sort((a, b) => a.priority - b.priority)) {\n const loc = rec.filePath ? `${rec.filePath}:${rec.lineNumber || '?'}` : '-';\n const issueShort = rec.issue.length > 50 ? rec.issue.substring(0, 50) + '...' : rec.issue;\n lines.push(`| ${rec.priority} | ${rec.category} | ${issueShort} | ${loc} | ${rec.estimatedEffort} |`);\n }\n lines.push('');\n\n // Detailed recommendations with fixes\n const withFixes = result.recommendations.filter((r) => r.suggestedFix);\n if (withFixes.length > 0) {\n lines.push('### Suggested Fixes');\n lines.push('');\n for (const rec of withFixes) {\n lines.push(`**${rec.issue}**`);\n if (rec.filePath) {\n lines.push(`- Location: \\`${rec.filePath}:${rec.lineNumber || '?'}\\``);\n }\n lines.push(`- Fix: ${rec.suggestedFix}`);\n lines.push('');\n }\n }\n }\n\n // Acceptance Criteria Checklist\n const met = result.requirements.filter((r) => r.status === 'met');\n const partial = result.requirements.filter((r) => r.status === 'partial');\n const notMet = result.requirements.filter((r) => r.status === 'not_met');\n\n lines.push('## Acceptance Criteria Checklist');\n lines.push('');\n for (const req of met) {\n lines.push(`- [x] ${req.id}: ${req.description}`);\n }\n for (const req of partial) {\n lines.push(`- [ ] ${req.id}: ${req.description} *(partial)*`);\n }\n for (const req of notMet) {\n lines.push(`- [ ] ${req.id}: ${req.description} *(not implemented)*`);\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * suggest_refactors tool - Identify refactoring opportunities\n */\nexport const suggestRefactorsTool: ToolDefinition = {\n tool: {\n name: 'suggest_refactors',\n description: `Analyze code and suggest refactoring opportunities for product planning.\n\nTakes source code and identifies:\n- Technical debt items\n- Refactoring opportunities\n- Architecture improvements\n- Performance optimizations\n- Maintainability issues\n\nProduces PM-friendly documentation for sprint planning.\n\nBest for: Technical debt prioritization and architecture evolution planning.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'Source code to analyze for refactoring opportunities',\n },\n codeContext: {\n type: 'string',\n description: 'Context about the codebase or feature',\n },\n priorities: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'performance',\n 'maintainability',\n 'scalability',\n 'security',\n 'testing',\n 'readability',\n ],\n },\n default: ['maintainability', 'performance'],\n description: 'What to prioritize in suggestions',\n },\n riskTolerance: {\n type: 'string',\n enum: ['low', 'medium', 'high'],\n default: 'medium',\n description: 'Risk tolerance for suggested changes',\n },\n teamSize: {\n type: 'string',\n enum: ['small', 'medium', 'large'],\n default: 'medium',\n description: 'Team size context for effort estimates',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['code'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const code = args.code as string;\n const codeContext = args.codeContext as string | undefined;\n const priorities = (args.priorities as string[]) || ['maintainability', 'performance'];\n const riskTolerance = (args.riskTolerance as string) || 'medium';\n const teamSize = (args.teamSize as string) || 'medium';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!code || code.trim().length === 0) {\n return errorResult('Source code is required for analysis');\n }\n\n const riskGuide: Record<string, string> = {\n low: 'Only suggest low-risk, incremental improvements. No major restructuring.',\n medium: 'Balance impact with risk. Include moderate restructuring where beneficial.',\n high: 'Include high-impact architectural changes. Transformative improvements acceptable.',\n };\n\n const systemPrompt = `You are a staff engineer specializing in code quality and technical debt management.\n\nAnalyze the code and suggest refactoring opportunities.\n\nPriorities: ${priorities.join(', ')}\nRisk Tolerance: ${riskGuide[riskTolerance]}\nTeam Context: ${teamSize} team\n${codeContext ? `Context: ${codeContext}` : ''}\n\nOutput Sections:\n\n1. **Executive Summary**\n - Overall code health score (1-10)\n - Top 3 priorities\n - Estimated total refactoring effort\n\n2. **Quick Wins** (Low effort, immediate impact)\n For each:\n - Issue description\n - Impact: [Performance/Maintainability/etc.]\n - Effort: Small\n - Risk: Low\n - Code location hint\n - Suggested approach\n\n3. **Medium-Term Improvements** (Moderate effort)\n For each:\n - Issue description\n - Business impact (why PM should care)\n - Effort: Medium (sprint-sized)\n - Risk assessment\n - Dependencies\n - Suggested approach\n\n4. **Strategic Refactors** (Significant effort)\n For each:\n - Current state and problem\n - Target state and benefits\n - Business justification\n - Effort: Large (multi-sprint)\n - Risk and mitigation\n - Incremental approach\n\n5. **Technical Debt Inventory**\n | Item | Type | Severity | Effort | Risk | Priority |\n |------|------|----------|--------|------|----------|\n\n6. **Anti-Patterns Identified**\n - Pattern name\n - Where found\n - Why it's problematic\n - Recommended pattern\n\n7. **Testing Debt**\n - Missing test coverage areas\n - Suggested testing improvements\n\n8. **Dependency Concerns**\n - Outdated dependencies\n - Security vulnerabilities risk\n - Upgrade recommendations\n\n9. **Sprint Planning Recommendations**\n - Suggested sprint allocation for tech debt\n - Recommended sequence of refactors\n - What to pair with feature work\n\n10. **Business Case Summary**\n - PM-friendly explanation of why these matter\n - Risk of not addressing\n - Velocity impact\n\nGuidelines:\n- Frame everything in terms of business impact\n- Provide concrete before/after examples where helpful\n- Consider incremental approaches\n- Note any blockers or dependencies`;\n\n const userMessage = `Analyze this code and suggest refactoring opportunities:\n\n\\`\\`\\`\n${code.length > 15000 ? code.substring(0, 15000) + '\\n// ... [truncated]' : code}\n\\`\\`\\`\n\nProvide comprehensive refactoring suggestions for sprint planning.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('suggest_refactors');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'suggest_refactors',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: priorities,\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to suggest refactors: ${message}`);\n }\n },\n\n requiredScope: 'tools:suggest_refactors',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion, createJsonCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, extname, relative, resolve } from 'path';\nimport type { BacklogReadyItem } from '@vaspera/shared';\n\ninterface OpenAPISpec {\n openapi: string;\n info: {\n title: string;\n version: string;\n description: string;\n };\n servers: Array<{ url: string; description: string }>;\n paths: Record<string, object>;\n components: {\n schemas: Record<string, object>;\n securitySchemes?: Record<string, object>;\n };\n security?: Array<Record<string, string[]>>;\n tags?: Array<{ name: string; description: string }>;\n}\n\ninterface ApiDocsOutput {\n format: string;\n spec: OpenAPISpec | object;\n summary: string;\n endpoints: number;\n}\n\n// ============================================================================\n// Route Discovery Functions\n// ============================================================================\n\ninterface DiscoveredRoute {\n filePath: string;\n relativePath: string;\n content: string;\n framework: string;\n}\n\n/**\n * Auto-discover API route files from a repository\n */\nfunction discoverApiRoutes(repoPath: string): DiscoveredRoute[] {\n const routes: DiscoveredRoute[] = [];\n const resolvedPath = resolve(repoPath);\n\n if (!existsSync(resolvedPath)) {\n return routes;\n }\n\n const ignoreDirs = new Set(['node_modules', 'dist', 'build', '.next', 'coverage', '.git']);\n const maxFileSize = 256 * 1024; // 256KB\n const maxFiles = 30;\n\n // Recursively find route files\n function walkDir(dir: string, depth = 0): void {\n if (depth > 8 || routes.length >= maxFiles) return;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (routes.length >= maxFiles) break;\n\n const fullPath = join(dir, entry.name);\n const relativePath = relative(resolvedPath, fullPath);\n\n // Skip ignored directories\n if (entry.isDirectory()) {\n if (!ignoreDirs.has(entry.name) && !entry.name.startsWith('.')) {\n walkDir(fullPath, depth + 1);\n }\n continue;\n }\n\n // Check if it's a potential route file\n if (!entry.isFile()) continue;\n\n const ext = extname(entry.name);\n if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) continue;\n\n // Check path patterns for routes\n const pathLower = relativePath.toLowerCase();\n const isRouteFile =\n pathLower.includes('/api/') ||\n pathLower.includes('/routes/') ||\n pathLower.includes('/route.') ||\n pathLower.includes('/handlers/') ||\n pathLower.includes('/controllers/') ||\n pathLower.includes('/endpoints/');\n\n if (!isRouteFile) continue;\n\n // Read the file\n try {\n const stat = statSync(fullPath);\n if (stat.size > maxFileSize) continue;\n\n const content = readFileSync(fullPath, 'utf-8');\n\n // Detect framework from content\n let framework = 'generic';\n if (content.includes('NextRequest') || content.includes('NextResponse') || /export\\s+(async\\s+)?function\\s+(GET|POST|PUT|DELETE|PATCH)/i.test(content)) {\n framework = 'nextjs';\n } else if (content.includes('express') || content.includes('Router()') || /app\\.(get|post|put|delete|patch)\\(/i.test(content)) {\n framework = 'express';\n } else if (content.includes('fastify') || content.includes('FastifyInstance')) {\n framework = 'fastify';\n } else if (content.includes('Hono') || content.includes('c.json')) {\n framework = 'hono';\n }\n\n routes.push({\n filePath: fullPath,\n relativePath,\n content,\n framework,\n });\n } catch {\n // Skip files that can't be read\n }\n }\n } catch {\n // Skip directories that can't be read\n }\n }\n\n walkDir(resolvedPath);\n return routes;\n}\n\n/**\n * Detect the primary API framework from discovered routes\n */\nfunction detectPrimaryFramework(routes: DiscoveredRoute[]): string {\n const counts: Record<string, number> = {};\n\n for (const route of routes) {\n counts[route.framework] = (counts[route.framework] || 0) + 1;\n }\n\n let maxCount = 0;\n let primary = 'generic';\n\n for (const [framework, count] of Object.entries(counts)) {\n if (count > maxCount) {\n maxCount = count;\n primary = framework;\n }\n }\n\n return primary;\n}\n\n/**\n * Format discovered routes for API documentation prompt\n */\nfunction formatRoutesForPrompt(routes: DiscoveredRoute[], maxChars = 50000): string {\n const parts: string[] = [];\n let totalChars = 0;\n\n for (const route of routes) {\n const header = `\\n\\n// ========== ${route.relativePath} ==========\\n`;\n const content = route.content;\n\n if (totalChars + header.length + content.length > maxChars) {\n // Truncate remaining content\n const remaining = maxChars - totalChars - header.length - 100;\n if (remaining > 500) {\n parts.push(header + content.substring(0, remaining) + '\\n// ... [truncated]');\n }\n break;\n }\n\n parts.push(header + content);\n totalChars += header.length + content.length;\n }\n\n return parts.join('');\n}\n\n/**\n * Extract backlog-ready items from an OpenAPI spec\n */\nfunction extractBacklogItemsFromSpec(spec: OpenAPISpec): BacklogReadyItem[] {\n const items: BacklogReadyItem[] = [];\n\n // Extract implementation tasks for each endpoint\n if (spec.paths) {\n for (const [path, methods] of Object.entries(spec.paths)) {\n const methodsObj = methods as Record<string, { summary?: string; description?: string; tags?: string[]; operationId?: string }>;\n\n for (const [method, details] of Object.entries(methodsObj)) {\n if (['get', 'post', 'put', 'delete', 'patch'].includes(method.toLowerCase())) {\n const operationId = details.operationId || `${method}_${path.replace(/\\//g, '_').replace(/[{}]/g, '')}`;\n const summary = details.summary || `${method.toUpperCase()} ${path}`;\n const tags = details.tags || ['api'];\n\n items.push({\n category: 'api',\n suggestedType: 'task',\n title: `Implement ${method.toUpperCase()} ${path}`,\n description: details.description || `Implement the ${summary} endpoint`,\n acceptanceCriteria: [\n `Endpoint responds to ${method.toUpperCase()} requests at ${path}`,\n 'Request validation is implemented per OpenAPI schema',\n 'Response matches documented schema',\n 'Error cases return appropriate HTTP status codes',\n 'Authentication/authorization is enforced if required',\n ],\n priority: method.toLowerCase() === 'get' ? 'medium' : 'high',\n estimate: {\n value: method.toLowerCase() === 'get' ? 2 : 3,\n unit: 'points',\n confidence: 'medium',\n },\n labels: ['api', ...tags],\n source: {\n tool: 'generate_api_docs',\n section: `paths.${path}.${method}`,\n },\n metadata: {\n operationId,\n method: method.toUpperCase(),\n path,\n },\n });\n }\n }\n }\n }\n\n // Extract schema implementation tasks\n if (spec.components?.schemas) {\n const schemaCount = Object.keys(spec.components.schemas).length;\n if (schemaCount > 0) {\n items.push({\n category: 'api',\n suggestedType: 'task',\n title: `Implement ${schemaCount} API data models`,\n description: `Create TypeScript interfaces/types for the ${schemaCount} data models defined in the API spec`,\n acceptanceCriteria: [\n 'All schemas have corresponding TypeScript types',\n 'Types include proper validation decorators if using class-validator',\n 'Types are exported from a central location',\n ],\n priority: 'high',\n estimate: {\n value: Math.ceil(schemaCount / 3),\n unit: 'points',\n confidence: 'medium',\n },\n labels: ['api', 'types'],\n source: {\n tool: 'generate_api_docs',\n section: 'components.schemas',\n },\n metadata: {\n schemaNames: Object.keys(spec.components.schemas),\n },\n });\n }\n }\n\n // Extract authentication implementation task if security schemes exist\n if (spec.components?.securitySchemes) {\n const schemes = Object.keys(spec.components.securitySchemes);\n items.push({\n category: 'api',\n suggestedType: 'story',\n title: 'Implement API authentication',\n description: `Implement authentication using: ${schemes.join(', ')}`,\n acceptanceCriteria: [\n 'Authentication middleware is implemented',\n 'Protected endpoints require valid credentials',\n 'Invalid credentials return 401 Unauthorized',\n 'Missing credentials return appropriate error',\n ],\n priority: 'critical',\n estimate: {\n value: 5,\n unit: 'points',\n confidence: 'medium',\n },\n labels: ['api', 'security', 'authentication'],\n source: {\n tool: 'generate_api_docs',\n section: 'components.securitySchemes',\n },\n metadata: {\n securitySchemes: schemes,\n },\n });\n }\n\n return items;\n}\n\n/**\n * generate_api_docs tool - Generate API documentation from code\n */\nexport const generateApiDocsTool: ToolDefinition = {\n tool: {\n name: 'generate_api_docs',\n description: `Generate API documentation from source code.\n\nAnalyzes API routes and generates:\n- OpenAPI 3.1 specification\n- Endpoint summaries\n- Request/response schemas\n- Authentication requirements\n- Example payloads\n\nSupports REST APIs in TypeScript/JavaScript, Python, Go, and more.\n\nBest for: Creating or updating API documentation from code.`,\n inputSchema: {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n description: 'API route code to analyze (routes, controllers, handlers). Optional if repoPath is provided.',\n },\n repoPath: {\n type: 'string',\n description: 'Path to repository for auto-discovery of API routes. Will scan for route files automatically.',\n },\n framework: {\n type: 'string',\n enum: ['nextjs', 'express', 'fastify', 'hono', 'flask', 'fastapi', 'gin', 'generic'],\n default: 'generic',\n description: 'API framework being used. Auto-detected if repoPath is provided.',\n },\n format: {\n type: 'string',\n enum: ['openapi', 'markdown', 'both'],\n default: 'openapi',\n description: 'Output documentation format',\n },\n baseUrl: {\n type: 'string',\n description: 'Base URL for the API',\n },\n title: {\n type: 'string',\n description: 'API title for documentation',\n },\n version: {\n type: 'string',\n default: '1.0.0',\n description: 'API version',\n },\n includeExamples: {\n type: 'boolean',\n default: true,\n description: 'Whether to generate example payloads',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n forBacklog: {\n type: 'boolean',\n default: false,\n description: 'Extract backlog-ready items (API implementation tasks) alongside documentation',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n let code = args.code as string | undefined;\n const repoPath = args.repoPath as string | undefined;\n let framework = (args.framework as string) || 'generic';\n const format = (args.format as string) || 'openapi';\n const baseUrl = (args.baseUrl as string) || 'https://api.example.com';\n const title = (args.title as string) || 'API Documentation';\n const version = (args.version as string) || '1.0.0';\n const includeExamples = args.includeExamples !== false;\n const projectRoot = (args.projectRoot as string) || repoPath || process.cwd();\n const forBacklog = args.forBacklog === true;\n\n // If repoPath is provided, auto-discover API routes\n let discoveredRoutes: DiscoveredRoute[] = [];\n if (repoPath) {\n discoveredRoutes = discoverApiRoutes(repoPath);\n\n if (discoveredRoutes.length === 0) {\n return errorResult(`No API routes found in ${repoPath}. Looked for files in /api/, /routes/, /handlers/, /controllers/ directories.`);\n }\n\n // Auto-detect framework if not specified\n if (!args.framework) {\n framework = detectPrimaryFramework(discoveredRoutes);\n }\n\n // Format routes as code for the prompt\n code = formatRoutesForPrompt(discoveredRoutes);\n\n // Add discovery summary header\n const routeSummary = discoveredRoutes.map(r => `// - ${r.relativePath} (${r.framework})`).join('\\n');\n code = `// Auto-discovered ${discoveredRoutes.length} route files:\\n${routeSummary}\\n\\n${code}`;\n }\n\n if (!code || code.trim().length === 0) {\n return errorResult('Either \"code\" or \"repoPath\" is required for documentation generation');\n }\n\n const frameworkHints: Record<string, string> = {\n nextjs: 'Next.js App Router with route.ts files. Look for GET, POST, PUT, DELETE, PATCH exports.',\n express: 'Express.js with app.get(), app.post(), router patterns.',\n fastify: 'Fastify with fastify.get(), schema definitions.',\n hono: 'Hono framework with app.get(), c.json() patterns.',\n flask: 'Flask with @app.route decorators.',\n fastapi: 'FastAPI with @app.get() decorators and Pydantic models.',\n gin: 'Gin framework with r.GET(), r.POST() patterns.',\n generic: 'Generic API code - infer patterns from the code.',\n };\n\n const systemPrompt = `You are an API documentation expert who generates OpenAPI 3.1 specifications from code.\n\nFramework: ${framework}\n${frameworkHints[framework]}\n\nGenerate a complete OpenAPI 3.1 specification with:\n1. All endpoints with methods (GET, POST, PUT, DELETE, PATCH)\n2. Path parameters extracted from route patterns\n3. Query parameters from code analysis\n4. Request body schemas from TypeScript types or validation\n5. Response schemas for success and error cases\n6. Authentication requirements if detected\n7. Logical grouping with tags\n${includeExamples ? '8. Realistic example values for all schemas' : ''}\n\nOutput a JSON object with:\n{\n \"openapi\": \"3.1.0\",\n \"info\": { \"title\": \"${title}\", \"version\": \"${version}\", \"description\": \"...\" },\n \"servers\": [{ \"url\": \"${baseUrl}\", \"description\": \"...\" }],\n \"paths\": { \"/path\": { \"get\": {...}, \"post\": {...} } },\n \"components\": { \"schemas\": {...}, \"securitySchemes\": {...} },\n \"tags\": [{ \"name\": \"...\", \"description\": \"...\" }]\n}\n\nBe thorough - extract every endpoint, parameter, and type from the code.`;\n\n const userMessage = `Generate OpenAPI documentation from this ${framework} API code:\n\n\\`\\`\\`\n${code.length > 15000 ? code.substring(0, 15000) + '\\n// ... [truncated]' : code}\n\\`\\`\\`\n\nGenerate complete OpenAPI 3.1 specification.`;\n\n try {\n if (format === 'markdown') {\n // Generate markdown documentation\n const mdPrompt = `You are an API documentation expert. Generate clear, comprehensive markdown API documentation.\n\nInclude:\n1. Overview and authentication\n2. Each endpoint with method, path, description\n3. Parameters table (name, type, required, description)\n4. Request body examples\n5. Response examples\n6. Error codes\n\nFramework: ${framework}`;\n\n const result = await createCompletion({\n systemPrompt: mdPrompt,\n userMessage: `Document this API:\\n\\n\\`\\`\\`\\n${code.length > 12000 ? code.substring(0, 12000) + '\\n// ...' : code}\\n\\`\\`\\``,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('generate_api_docs');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_api_docs',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [framework],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n }\n\n // Generate OpenAPI spec (needs high maxTokens for large specs)\n const result = await createJsonCompletion<ApiDocsOutput>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n if (format === 'both') {\n // Also generate markdown summary\n const mdResult = await createCompletion({\n systemPrompt: 'Summarize this OpenAPI spec as readable markdown documentation.',\n userMessage: JSON.stringify(result.data, null, 2),\n model: 'fast',\n maxTokens: 2000,\n });\n\n const combinedContent = `# ${title}\\n\\n${mdResult.text}\\n\\n---\\n\\n## OpenAPI Specification\\n\\n\\`\\`\\`json\\n${JSON.stringify(result.data, null, 2)}\\n\\`\\`\\``;\n const combinedTokens = totalTokens + mdResult.inputTokens + mdResult.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('generate_api_docs');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_api_docs',\n category: defaults.category,\n filename: defaults.filename,\n content: combinedContent,\n format: 'md',\n inputs: [framework],\n tokensUsed: combinedTokens,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: combinedContent + formatSavedPath(saved),\n },\n ],\n tokensUsed: combinedTokens,\n };\n }\n\n // Auto-save output to project's vasperaPM folder (JSON format)\n const defaults = getToolDefaults('generate_api_docs');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_api_docs',\n category: defaults.category,\n filename: defaults.filename,\n content: JSON.stringify(result.data, null, 2),\n format: 'json',\n inputs: [framework],\n tokensUsed: totalTokens,\n });\n\n // Extract backlog items if requested\n let outputText = JSON.stringify(result.data, null, 2);\n if (forBacklog) {\n const spec = result.data as unknown as OpenAPISpec;\n const backlogItems = extractBacklogItemsFromSpec(spec);\n\n if (backlogItems.length > 0) {\n outputText += '\\n\\n---\\n\\n## Extracted Backlog Items\\n\\n';\n outputText += `Found ${backlogItems.length} implementation tasks:\\n\\n`;\n\n for (const item of backlogItems) {\n outputText += `### ${item.title}\\n`;\n outputText += `- **Type:** ${item.suggestedType}\\n`;\n outputText += `- **Priority:** ${item.priority}\\n`;\n outputText += `- **Estimate:** ${item.estimate?.value} ${item.estimate?.unit}\\n`;\n outputText += `- **Labels:** ${item.labels.join(', ')}\\n`;\n outputText += `- **Description:** ${item.description}\\n`;\n if (item.acceptanceCriteria && item.acceptanceCriteria.length > 0) {\n outputText += `- **Acceptance Criteria:**\\n`;\n for (const ac of item.acceptanceCriteria) {\n outputText += ` - ${ac}\\n`;\n }\n }\n outputText += '\\n';\n }\n\n // Also save backlog items as JSON\n saveToolOutput({\n projectRoot,\n toolName: 'generate_api_docs',\n category: 'backlog',\n filename: 'api_backlog_items',\n content: JSON.stringify(backlogItems, null, 2),\n format: 'json',\n inputs: [framework, 'forBacklog'],\n tokensUsed: 0,\n });\n }\n }\n\n return {\n content: [\n {\n type: 'text',\n text: outputText + formatSavedPath(saved),\n },\n ],\n tokensUsed: totalTokens,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate API docs: ${message}`);\n }\n },\n\n requiredScope: 'tools:generate_api_docs',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * dependency_audit tool - Audit project dependencies\n */\nexport const dependencyAuditTool: ToolDefinition = {\n tool: {\n name: 'dependency_audit',\n description: `Audit project dependencies for security, updates, and health.\n\nAnalyzes package.json, requirements.txt, go.mod, or similar and provides:\n- Security vulnerability assessment\n- Outdated package identification\n- License compliance check\n- Bundle size impact analysis\n- Maintenance health scores\n- Upgrade recommendations with breaking change warnings\n\nBest for: Pre-release dependency review and security audits.`,\n inputSchema: {\n type: 'object',\n properties: {\n manifest: {\n type: 'string',\n description: 'Dependency manifest content (package.json, requirements.txt, etc.)',\n },\n lockfile: {\n type: 'string',\n description: 'Optional lockfile content for version pinning analysis',\n },\n manifestType: {\n type: 'string',\n enum: ['npm', 'yarn', 'pnpm', 'pip', 'poetry', 'go', 'cargo', 'maven', 'gradle'],\n default: 'npm',\n description: 'Package manager type',\n },\n checkTypes: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['security', 'updates', 'licenses', 'maintenance', 'size', 'duplicates'],\n },\n default: ['security', 'updates', 'maintenance'],\n description: 'Types of checks to perform',\n },\n severity: {\n type: 'string',\n enum: ['all', 'moderate', 'high', 'critical'],\n default: 'moderate',\n description: 'Minimum severity level to report',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['manifest'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const manifest = args.manifest as string;\n const lockfile = args.lockfile as string | undefined;\n const manifestType = (args.manifestType as string) || 'npm';\n const checkTypes = (args.checkTypes as string[]) || ['security', 'updates', 'maintenance'];\n const severity = (args.severity as string) || 'moderate';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!manifest || manifest.trim().length === 0) {\n return errorResult('Dependency manifest is required');\n }\n\n const severityLevels: Record<string, string> = {\n all: 'Report all issues including informational',\n moderate: 'Report moderate severity and above',\n high: 'Report only high and critical issues',\n critical: 'Report only critical issues',\n };\n\n const systemPrompt = `You are a security-focused DevOps engineer performing a comprehensive dependency audit.\n\nPackage Manager: ${manifestType}\nCheck Types: ${checkTypes.join(', ')}\nSeverity Threshold: ${severityLevels[severity]}\n\nProvide a thorough audit report with:\n\n1. **Executive Summary**\n - Overall health score (A-F)\n - Critical issues count\n - Recommended actions\n\n2. **Security Vulnerabilities** (if checked)\n | Package | Version | Vulnerability | Severity | CVE | Fix Version |\n |---------|---------|---------------|----------|-----|-------------|\n - Include known CVEs where applicable\n - Note if no known vulnerabilities\n\n3. **Outdated Packages** (if checked)\n | Package | Current | Latest | Type | Breaking Changes |\n |---------|---------|--------|------|------------------|\n - Distinguish patch, minor, major updates\n - Flag breaking changes in major updates\n\n4. **License Compliance** (if checked)\n | Package | License | Risk Level | Notes |\n |---------|---------|------------|-------|\n - Flag copyleft licenses (GPL, AGPL)\n - Note license compatibility issues\n\n5. **Maintenance Health** (if checked)\n | Package | Last Update | Weekly Downloads | Issues | Health |\n |---------|-------------|------------------|--------|--------|\n - Flag abandoned packages (>2 years no update)\n - Note packages with many open issues\n\n6. **Size Impact** (if checked)\n | Package | Size | Gzipped | Alternatives |\n |---------|------|---------|--------------|\n - Identify heavy dependencies\n - Suggest lighter alternatives\n\n7. **Duplicate Dependencies** (if checked)\n - Identify packages included multiple times\n - Note version conflicts\n\n8. **Recommendations**\n - Prioritized list of actions\n - Safe upgrade paths\n - Packages to consider replacing\n\nBase your analysis on common knowledge about popular packages. Be conservative with security assessments - note when you're uncertain.`;\n\n let userMessage = `Audit these dependencies:\n\n## Manifest (${manifestType})\n\\`\\`\\`\n${manifest.length > 10000 ? manifest.substring(0, 10000) + '\\n... [truncated]' : manifest}\n\\`\\`\\``;\n\n if (lockfile) {\n userMessage += `\\n\\n## Lockfile\\n\\`\\`\\`\\n${lockfile.length > 5000 ? lockfile.substring(0, 5000) + '\\n... [truncated]' : lockfile}\\n\\`\\`\\``;\n }\n\n userMessage += '\\n\\nProvide a comprehensive dependency audit.';\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('dependency_audit');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'dependency_audit',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: checkTypes,\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to audit dependencies: ${message}`);\n }\n },\n\n requiredScope: 'tools:dependency_audit',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * estimate_migration tool - Estimate migration effort\n */\nexport const estimateMigrationTool: ToolDefinition = {\n tool: {\n name: 'estimate_migration',\n description: `Estimate the effort required for a code migration or major upgrade.\n\nAnalyzes current code and target state to provide:\n- Effort estimation (story points, days)\n- Risk assessment\n- Breaking changes analysis\n- Migration path recommendations\n- Rollback strategy\n\nSupports: Framework upgrades, language migrations, architecture changes, dependency updates.\n\nBest for: Sprint planning for major technical initiatives.`,\n inputSchema: {\n type: 'object',\n properties: {\n currentCode: {\n type: 'string',\n description: 'Current codebase sample to analyze',\n },\n migrationType: {\n type: 'string',\n enum: [\n 'framework_upgrade',\n 'language_migration',\n 'architecture_change',\n 'dependency_upgrade',\n 'database_migration',\n 'cloud_migration',\n 'monolith_to_microservices',\n 'other',\n ],\n description: 'Type of migration being planned',\n },\n from: {\n type: 'string',\n description: 'Current technology/version (e.g., \"React 17\", \"Python 2.7\")',\n },\n to: {\n type: 'string',\n description: 'Target technology/version (e.g., \"React 18\", \"Python 3.11\")',\n },\n codebaseSize: {\n type: 'string',\n enum: ['small', 'medium', 'large', 'enterprise'],\n default: 'medium',\n description: 'Approximate codebase size',\n },\n teamSize: {\n type: 'number',\n default: 3,\n description: 'Number of developers available for migration',\n },\n constraints: {\n type: 'string',\n description: 'Any constraints (timeline, budget, parallel development)',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: ['migrationType', 'from', 'to'],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const currentCode = args.currentCode as string | undefined;\n const migrationType = args.migrationType as string;\n const from = args.from as string;\n const to = args.to as string;\n const codebaseSize = (args.codebaseSize as string) || 'medium';\n const teamSize = (args.teamSize as number) || 3;\n const constraints = args.constraints as string | undefined;\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n if (!migrationType || !from || !to) {\n return errorResult('Migration type, from, and to are required');\n }\n\n const sizeMultipliers: Record<string, string> = {\n small: '<10k LOC, few dependencies',\n medium: '10k-50k LOC, moderate complexity',\n large: '50k-200k LOC, many integrations',\n enterprise: '>200k LOC, complex architecture',\n };\n\n const systemPrompt = `You are a senior technical architect who specializes in migration planning.\n\nEstimate the effort for migrating from \"${from}\" to \"${to}\".\n\nMigration Type: ${migrationType}\nCodebase Size: ${codebaseSize} (${sizeMultipliers[codebaseSize]})\nTeam Size: ${teamSize} developers\n${constraints ? `Constraints: ${constraints}` : ''}\n\nProvide a comprehensive migration estimate with:\n\n1. **Executive Summary**\n - Total estimated effort (story points and calendar time)\n - Risk level (Low/Medium/High/Critical)\n - Recommended approach (Big bang / Incremental / Strangler fig)\n\n2. **Effort Breakdown**\n | Phase | Tasks | Story Points | Calendar Days | Parallel? |\n |-------|-------|--------------|---------------|-----------|\n - Phase 1: Assessment & Planning\n - Phase 2: Infrastructure Setup\n - Phase 3: Code Migration\n - Phase 4: Testing & Validation\n - Phase 5: Deployment & Cutover\n\n3. **Breaking Changes Analysis**\n | Area | Impact | Effort | Notes |\n |------|--------|--------|-------|\n - API changes\n - Dependency updates\n - Configuration changes\n - Data format changes\n\n4. **Risk Assessment**\n | Risk | Probability | Impact | Mitigation |\n |------|-------------|--------|------------|\n\n5. **Migration Path**\n - Step-by-step migration strategy\n - Dependencies between steps\n - Parallel work opportunities\n\n6. **Testing Strategy**\n - Unit test updates needed\n - Integration test requirements\n - Performance benchmarking\n - Regression testing approach\n\n7. **Rollback Strategy**\n - Feature flags approach\n - Database rollback plan\n - Traffic shifting strategy\n\n8. **Resource Requirements**\n - Skills needed\n - Infrastructure for parallel environments\n - Tools and automation\n\n9. **Assumptions & Caveats**\n - What could change the estimate\n - Unknown risks\n\n10. **Sprint Breakdown** (for ${teamSize} developers)\n - Sprint 1: ...\n - Sprint 2: ...\n - etc.\n\nBe realistic and include buffer for unknowns. Better to overestimate than underestimate.`;\n\n let userMessage = `Estimate migration effort for:\n\n**From:** ${from}\n**To:** ${to}\n**Type:** ${migrationType}`;\n\n if (currentCode) {\n userMessage += `\\n\\n**Sample of Current Code:**\\n\\`\\`\\`\\n${currentCode.length > 8000 ? currentCode.substring(0, 8000) + '\\n// ...' : currentCode}\\n\\`\\`\\``;\n }\n\n userMessage += '\\n\\nProvide a comprehensive migration estimate.';\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 5000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output to project's vasperaPM folder\n const defaults = getToolDefaults('estimate_migration');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'estimate_migration',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [migrationType, from, to],\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to estimate migration: ${message}`);\n }\n },\n\n requiredScope: 'tools:estimate_migration',\n};\n","/**\n * VasperaPM Multi-Agent Architecture\n *\n * Base types and interfaces for the agent system.\n * Implements coordinated multi-agent verification with planning,\n * execution, self-correction, and debate capabilities.\n */\n\n// ============================================================================\n// Agent Base Types\n// ============================================================================\n\nexport type AgentRole =\n | 'orchestrator'\n | 'discovery'\n | 'analyzer'\n | 'validator'\n | 'specialist';\n\nexport type AgentStatus =\n | 'idle'\n | 'planning'\n | 'executing'\n | 'waiting'\n | 'complete'\n | 'error';\n\nexport type MessageType =\n | 'task' // Task assignment from orchestrator\n | 'result' // Task completion result\n | 'query' // Request for information\n | 'response' // Response to query\n | 'challenge' // Challenge a finding (for debate)\n | 'defense' // Defend a finding (for debate)\n | 'consensus' // Agreed upon result after debate\n | 'escalation' // Escalate to orchestrator\n | 'broadcast'; // Broadcast to all agents\n\nexport type Priority = 'critical' | 'high' | 'medium' | 'low';\n\n// ============================================================================\n// Message System\n// ============================================================================\n\nexport interface AgentMessage {\n id: string;\n type: MessageType;\n from: AgentRole;\n to: AgentRole | 'all';\n timestamp: string;\n priority: Priority;\n payload: unknown;\n correlationId?: string; // Links related messages\n replyTo?: string; // Message this is replying to\n}\n\nexport interface TaskMessage extends AgentMessage {\n type: 'task';\n payload: {\n taskId: string;\n taskType: string;\n description: string;\n inputs: Record<string, unknown>;\n deadline?: string;\n maxRetries?: number;\n };\n}\n\nexport interface ResultMessage extends AgentMessage {\n type: 'result';\n payload: {\n taskId: string;\n success: boolean;\n data: unknown;\n confidence: number;\n tokensUsed: { input: number; output: number };\n executionTime: number;\n errors?: string[];\n };\n}\n\nexport interface ChallengeMessage extends AgentMessage {\n type: 'challenge';\n payload: {\n findingId: string;\n finding: unknown;\n reason: string;\n evidence: string[];\n suggestedCorrection?: unknown;\n };\n}\n\nexport interface DefenseMessage extends AgentMessage {\n type: 'defense';\n payload: {\n findingId: string;\n originalFinding: unknown;\n defenseArguments: string[];\n additionalEvidence: string[];\n confidenceAfterChallenge: number;\n };\n}\n\n// ============================================================================\n// Agent Interface\n// ============================================================================\n\nexport interface AgentContext {\n projectPath: string;\n outputPath: string;\n config: AgentConfig;\n memory: AgentMemory;\n}\n\nexport interface AgentConfig {\n maxTokensPerCall: number;\n maxRetries: number;\n debateEnabled: boolean;\n confidenceThreshold: number; // Below this, trigger debate\n model: 'fast' | 'balanced' | 'quality';\n}\n\nexport interface AgentMemory {\n /** Previous findings from this project */\n previousFindings: Map<string, unknown>;\n /** Patterns learned from verification history */\n patterns: Map<string, VerificationPattern>;\n /** Framework-specific rules */\n frameworkRules: Map<string, FrameworkRule[]>;\n}\n\nexport interface VerificationPattern {\n id: string;\n description: string;\n category: string;\n confidence: number;\n occurrences: number;\n lastSeen: string;\n}\n\nexport interface FrameworkRule {\n id: string;\n framework: string;\n rule: string;\n severity: Priority;\n autoFix?: string;\n}\n\n// ============================================================================\n// Agent Base Class Interface\n// ============================================================================\n\nexport interface Agent {\n role: AgentRole;\n status: AgentStatus;\n\n /** Initialize the agent with context */\n initialize(context: AgentContext): Promise<void>;\n\n /** Process an incoming message */\n processMessage(message: AgentMessage): Promise<AgentMessage | null>;\n\n /** Execute a task */\n execute(task: TaskMessage): Promise<ResultMessage>;\n\n /** Get current agent state */\n getState(): AgentState;\n\n /** Shutdown the agent */\n shutdown(): Promise<void>;\n}\n\nexport interface AgentState {\n role: AgentRole;\n status: AgentStatus;\n currentTask?: string;\n pendingMessages: number;\n tokensUsed: { input: number; output: number };\n tasksCompleted: number;\n errors: string[];\n}\n\n// ============================================================================\n// Orchestrator-Specific Types\n// ============================================================================\n\nexport interface VerificationPlan {\n id: string;\n projectPath: string;\n createdAt: string;\n phases: VerificationPhase[];\n estimatedTokens: number;\n estimatedTime: number; // milliseconds\n}\n\nexport interface VerificationPhase {\n id: string;\n name: string;\n description: string;\n agent: AgentRole;\n dependencies: string[]; // Phase IDs that must complete first\n tasks: PlannedTask[];\n status: 'pending' | 'in_progress' | 'complete' | 'failed';\n}\n\nexport interface PlannedTask {\n id: string;\n type: string;\n description: string;\n inputs: Record<string, unknown>;\n estimatedTokens: number;\n priority: Priority;\n}\n\n// ============================================================================\n// Discovery Agent Types\n// ============================================================================\n\nexport interface DiscoveryTask {\n type: 'discover_docs' | 'discover_code' | 'categorize' | 'build_graph';\n path: string;\n options?: {\n maxDepth?: number;\n includeContent?: boolean;\n filePatterns?: string[];\n };\n}\n\nexport interface DiscoveryResult {\n files: DiscoveredFile[];\n graph: DependencyGraph;\n summary: DiscoverySummary;\n}\n\nexport interface DiscoveredFile {\n path: string;\n relativePath: string;\n type: 'doc' | 'code';\n category: string;\n language?: string;\n size: number;\n hash: string;\n content?: string;\n imports?: string[];\n exports?: string[];\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, GraphNode>;\n edges: GraphEdge[];\n}\n\nexport interface GraphNode {\n id: string;\n path: string;\n type: 'doc' | 'code';\n category: string;\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n type: 'imports' | 'references' | 'documents' | 'implements';\n}\n\nexport interface DiscoverySummary {\n totalDocs: number;\n totalCode: number;\n docsByCategory: Record<string, number>;\n codeByLanguage: Record<string, number>;\n frameworks: string[];\n}\n\n// ============================================================================\n// Analyzer Agent Types\n// ============================================================================\n\nexport interface AnalysisTask {\n type: 'extract_requirements' | 'extract_features' | 'map_requirements' | 'detect_drift';\n content: string;\n source: 'docs' | 'code';\n context?: {\n framework?: string;\n previousRequirements?: Requirement[];\n };\n}\n\nexport interface Requirement {\n id: string;\n description: string;\n category: RequirementCategory;\n source: 'docs' | 'code' | 'both';\n sourceFile?: string;\n sourceLine?: number;\n priority?: Priority;\n dependencies?: string[];\n}\n\nexport type RequirementCategory =\n | 'feature'\n | 'api'\n | 'security'\n | 'performance'\n | 'ui'\n | 'data'\n | 'integration'\n | 'infrastructure';\n\nexport interface AnalysisResult {\n requirements: Requirement[];\n mappings: RequirementMapping[];\n confidence: number;\n}\n\nexport interface RequirementMapping {\n docRequirementId: string;\n codeFeatureId?: string;\n matchScore: number;\n evidence: string[];\n}\n\n// ============================================================================\n// Validator Agent Types\n// ============================================================================\n\nexport interface ValidationTask {\n type: 'cross_validate' | 'debate' | 'score_confidence' | 'flag_disputes';\n findings: VerifiedRequirement[];\n context?: {\n originalDocs?: string;\n originalCode?: string;\n };\n}\n\nexport type VerificationStatus =\n | 'verified'\n | 'drift'\n | 'undocumented'\n | 'unimplemented'\n | 'disputed';\n\nexport type DriftSeverity = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface VerifiedRequirement {\n requirement: Requirement;\n status: VerificationStatus;\n confidence: number;\n documentedBehavior?: string;\n implementedBehavior?: string;\n evidence: {\n docReferences: string[];\n codeReferences: string[];\n };\n drift?: {\n severity: DriftSeverity;\n description: string;\n recommendation: 'update_docs' | 'update_code' | 'needs_discussion';\n };\n debate?: DebateRecord;\n}\n\nexport interface DebateRecord {\n initiated: string;\n challenger: AgentRole;\n defender: AgentRole;\n rounds: DebateRound[];\n outcome: 'upheld' | 'overturned' | 'modified';\n finalConfidence: number;\n}\n\nexport interface DebateRound {\n round: number;\n challenge: string;\n defense: string;\n judgeNotes?: string;\n}\n\nexport interface ValidationResult {\n verified: VerifiedRequirement[];\n summary: VerificationSummary;\n disputes: VerifiedRequirement[];\n ruleResults?: RuleValidationResult;\n}\n\nexport interface RuleValidationResult {\n results: Array<{\n ruleId: string;\n ruleName: string;\n passed: boolean;\n severity: 'error' | 'warning' | 'info';\n message: string;\n }>;\n passed: number;\n failed: number;\n warnings: number;\n}\n\nexport interface VerificationSummary {\n total: number;\n verified: number;\n drift: number;\n undocumented: number;\n unimplemented: number;\n disputed: number;\n overallConfidence: number;\n debatesTriggered: number;\n debatesOverturned: number;\n rulesExecuted?: number;\n rulesPassed?: number;\n gitAnalysis?: GitAnalysisSummary;\n}\n\n// ============================================================================\n// Git Analysis Types (for integration)\n// ============================================================================\n\nexport interface GitAnalysisSummary {\n /** Average freshness score across all docs (0-100) */\n averageFreshness: number;\n /** Number of stale documents found */\n staleDocCount: number;\n /** Number of code-doc desync pairs detected */\n desyncPairCount: number;\n /** Number of high-risk files identified */\n highRiskFileCount: number;\n /** Overall drift risk level */\n overallDriftRisk: 'critical' | 'high' | 'medium' | 'low';\n}\n\nexport interface DocFreshnessInfo {\n /** Freshness score 0-100 (higher = fresher) */\n freshnessScore: number;\n /** Days since last update */\n daysSinceUpdate: number;\n /** Last author name */\n lastAuthor: string;\n /** Is this document considered stale? */\n isStale: boolean;\n}\n\nexport interface VerifiedRequirementWithGit extends VerifiedRequirement {\n /** Documentation freshness information */\n docFreshness?: DocFreshnessInfo;\n /** Git-based insight about potential drift */\n gitInsight?: string;\n}\n\n// ============================================================================\n// Agent Event System\n// ============================================================================\n\nexport type AgentEventType =\n | 'agent:started'\n | 'agent:task_started'\n | 'agent:task_completed'\n | 'agent:error'\n | 'agent:debate_started'\n | 'agent:debate_resolved'\n | 'orchestrator:plan_created'\n | 'orchestrator:phase_started'\n | 'orchestrator:phase_completed'\n | 'orchestrator:analysis_complete';\n\nexport interface AgentEvent {\n type: AgentEventType;\n timestamp: string;\n agent: AgentRole;\n data: unknown;\n}\n\nexport type AgentEventHandler = (event: AgentEvent) => void;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nexport function createMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function createTaskId(): string {\n return `task_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function createMessage(\n type: MessageType,\n from: AgentRole,\n to: AgentRole | 'all',\n payload: unknown,\n options: Partial<AgentMessage> = {}\n): AgentMessage {\n return {\n id: createMessageId(),\n type,\n from,\n to,\n timestamp: new Date().toISOString(),\n priority: 'medium',\n payload,\n ...options,\n };\n}\n\nexport function createTaskMessage(\n from: AgentRole,\n to: AgentRole,\n taskType: string,\n description: string,\n inputs: Record<string, unknown>,\n priority: Priority = 'medium'\n): TaskMessage {\n return {\n id: createMessageId(),\n type: 'task',\n from,\n to,\n timestamp: new Date().toISOString(),\n priority,\n payload: {\n taskId: createTaskId(),\n taskType,\n description,\n inputs,\n },\n };\n}\n\nexport function createResultMessage(\n from: AgentRole,\n to: AgentRole,\n taskId: string,\n success: boolean,\n data: unknown,\n confidence: number,\n tokensUsed: { input: number; output: number },\n executionTime: number,\n errors?: string[]\n): ResultMessage {\n return {\n id: createMessageId(),\n type: 'result',\n from,\n to,\n timestamp: new Date().toISOString(),\n priority: success ? 'medium' : 'high',\n payload: {\n taskId,\n success,\n data,\n confidence,\n tokensUsed,\n executionTime,\n errors,\n },\n };\n}\n","/**\n * Base Agent Implementation\n *\n * Provides common functionality for all VasperaPM agents.\n */\n\nimport {\n Agent,\n AgentRole,\n AgentStatus,\n AgentContext,\n AgentState,\n AgentMessage,\n TaskMessage,\n ResultMessage,\n AgentEvent,\n AgentEventHandler,\n AgentEventType,\n createResultMessage,\n} from './types.js';\n\nexport abstract class BaseAgent implements Agent {\n role: AgentRole;\n status: AgentStatus = 'idle';\n\n protected context: AgentContext | null = null;\n protected messageQueue: AgentMessage[] = [];\n protected tokensUsed = { input: 0, output: 0 };\n protected tasksCompleted = 0;\n protected errors: string[] = [];\n protected eventHandlers: Map<AgentEventType, AgentEventHandler[]> = new Map();\n\n constructor(role: AgentRole) {\n this.role = role;\n }\n\n async initialize(context: AgentContext): Promise<void> {\n this.context = context;\n this.status = 'idle';\n this.emitEvent('agent:started', { context });\n }\n\n async processMessage(message: AgentMessage): Promise<AgentMessage | null> {\n if (message.type === 'task') {\n return this.execute(message as TaskMessage);\n }\n\n // Queue other messages for processing\n this.messageQueue.push(message);\n return null;\n }\n\n abstract execute(task: TaskMessage): Promise<ResultMessage>;\n\n getState(): AgentState {\n return {\n role: this.role,\n status: this.status,\n currentTask: undefined,\n pendingMessages: this.messageQueue.length,\n tokensUsed: { ...this.tokensUsed },\n tasksCompleted: this.tasksCompleted,\n errors: [...this.errors],\n };\n }\n\n async shutdown(): Promise<void> {\n this.status = 'idle';\n this.messageQueue = [];\n }\n\n // Event system\n on(eventType: AgentEventType, handler: AgentEventHandler): void {\n if (!this.eventHandlers.has(eventType)) {\n this.eventHandlers.set(eventType, []);\n }\n this.eventHandlers.get(eventType)!.push(handler);\n }\n\n protected emitEvent(type: AgentEventType, data: unknown): void {\n const event: AgentEvent = {\n type,\n timestamp: new Date().toISOString(),\n agent: this.role,\n data,\n };\n\n const handlers = this.eventHandlers.get(type) || [];\n for (const handler of handlers) {\n try {\n handler(event);\n } catch (err) {\n console.error(`Error in event handler for ${type}:`, err);\n }\n }\n }\n\n protected addTokens(input: number, output: number): void {\n this.tokensUsed.input += input;\n this.tokensUsed.output += output;\n }\n\n protected addError(error: string): void {\n this.errors.push(error);\n this.emitEvent('agent:error', { error });\n }\n\n protected createSuccessResult(\n taskId: string,\n data: unknown,\n confidence: number,\n tokensUsed: { input: number; output: number },\n executionTime: number\n ): ResultMessage {\n return createResultMessage(\n this.role,\n 'orchestrator',\n taskId,\n true,\n data,\n confidence,\n tokensUsed,\n executionTime\n );\n }\n\n protected createErrorResult(\n taskId: string,\n error: string,\n executionTime: number\n ): ResultMessage {\n this.addError(error);\n return createResultMessage(\n this.role,\n 'orchestrator',\n taskId,\n false,\n null,\n 0,\n { input: 0, output: 0 },\n executionTime,\n [error]\n );\n }\n}\n","/**\n * Discovery Agent\n *\n * Responsible for:\n * - Finding documentation files\n * - Finding code files\n * - Categorizing files by type and purpose\n * - Building dependency graphs\n * - Detecting frameworks and tech stack\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join, extname, relative, basename } from 'path';\nimport { createHash } from 'crypto';\nimport { BaseAgent } from './base-agent.js';\nimport {\n TaskMessage,\n ResultMessage,\n DiscoveredFile,\n DependencyGraph,\n DiscoverySummary,\n GraphNode,\n GraphEdge,\n} from './types.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst EXCLUDE_PATHS = [\n 'node_modules',\n '.git',\n '.next',\n '.vercel',\n 'dist',\n 'build',\n 'coverage',\n '.turbo',\n '.cache',\n '__pycache__',\n 'venv',\n '.venv',\n 'vendor',\n 'target',\n '.idea',\n '.vscode',\n];\n\nconst DOC_EXTENSIONS = ['.md', '.mdx', '.txt', '.rst', '.adoc'];\nconst SPEC_EXTENSIONS = ['.yaml', '.yml', '.json'];\n\nconst DOC_CATEGORIES: Record<string, RegExp[]> = {\n readme: [/^readme/i, /^about/i],\n prd: [/^prd/i, /^spec/i, /^requirements/i, /^features/i],\n api: [/^api/i, /^openapi/i, /^swagger/i, /^endpoints/i],\n architecture: [/^architecture/i, /^design/i, /^adr/i, /^decisions/i, /^tech/i],\n changelog: [/^changelog/i, /^history/i, /^releases/i, /^version/i],\n contributing: [/^contributing/i, /^develop/i, /^setup/i],\n};\n\nconst CODE_EXTENSIONS: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.py': 'python',\n '.go': 'go',\n '.java': 'java',\n '.rs': 'rust',\n '.rb': 'ruby',\n '.php': 'php',\n '.cs': 'csharp',\n '.swift': 'swift',\n '.kt': 'kotlin',\n};\n\nconst CODE_CATEGORIES: Record<string, RegExp[]> = {\n routes: [/routes?/i, /api/i, /endpoints?/i, /handlers?/i, /controllers?/i],\n components: [/components?/i, /views?/i, /pages?/i, /screens?/i, /ui/i],\n utils: [/utils?/i, /helpers?/i, /lib/i, /shared/i, /common/i],\n types: [/types?/i, /interfaces?/i, /models?/i, /schemas?/i, /dtos?/i],\n tests: [/tests?/i, /__tests__/i, /spec/i, /\\.test\\./i, /\\.spec\\./i],\n config: [/config/i, /settings?/i, /env/i],\n};\n\nconst FRAMEWORK_INDICATORS: Record<string, string[]> = {\n nextjs: ['next.config.js', 'next.config.mjs', 'next.config.ts', '.next'],\n react: ['react', 'react-dom'],\n vue: ['vue.config.js', 'nuxt.config.js', '.nuxt'],\n angular: ['angular.json', 'angular.cli.json'],\n express: ['express'],\n fastify: ['fastify'],\n nestjs: ['@nestjs/core'],\n django: ['django', 'manage.py'],\n flask: ['flask'],\n fastapi: ['fastapi'],\n rails: ['Gemfile', 'config/routes.rb'],\n spring: ['pom.xml', 'build.gradle'],\n};\n\n// ============================================================================\n// Discovery Agent\n// ============================================================================\n\nexport class DiscoveryAgent extends BaseAgent {\n private maxDepth = 10;\n private maxFileSize = 1024 * 1024; // 1MB\n private includeContent = true;\n\n constructor() {\n super('discovery');\n }\n\n async execute(task: TaskMessage): Promise<ResultMessage> {\n const startTime = Date.now();\n this.status = 'executing';\n this.emitEvent('agent:task_started', { taskId: task.payload.taskId });\n\n try {\n const { taskType, inputs } = task.payload;\n let result: unknown;\n\n switch (taskType) {\n case 'discover_all':\n result = await this.discoverAll(inputs.path as string, inputs.options as Record<string, unknown>);\n break;\n case 'discover_docs':\n result = await this.discoverDocs(inputs.path as string);\n break;\n case 'discover_code':\n result = await this.discoverCode(inputs.path as string);\n break;\n case 'build_graph':\n result = await this.buildDependencyGraph(inputs.files as DiscoveredFile[]);\n break;\n case 'detect_frameworks':\n result = await this.detectFrameworks(inputs.path as string);\n break;\n default:\n throw new Error(`Unknown task type: ${taskType}`);\n }\n\n const executionTime = Date.now() - startTime;\n this.tasksCompleted++;\n this.status = 'complete';\n this.emitEvent('agent:task_completed', { taskId: task.payload.taskId, success: true });\n\n return this.createSuccessResult(\n task.payload.taskId,\n result,\n 100, // Discovery doesn't use AI, 100% confidence\n { input: 0, output: 0 },\n executionTime\n );\n } catch (err) {\n const executionTime = Date.now() - startTime;\n const error = err instanceof Error ? err.message : 'Unknown error';\n this.status = 'error';\n\n return this.createErrorResult(task.payload.taskId, error, executionTime);\n }\n }\n\n /**\n * Full discovery: docs, code, graph, and frameworks\n */\n async discoverAll(\n projectPath: string,\n options?: Record<string, unknown>\n ): Promise<{\n docs: DiscoveredFile[];\n code: DiscoveredFile[];\n graph: DependencyGraph;\n summary: DiscoverySummary;\n }> {\n if (options?.maxDepth) this.maxDepth = options.maxDepth as number;\n if (options?.maxFileSize) this.maxFileSize = options.maxFileSize as number;\n if (options?.includeContent !== undefined) this.includeContent = options.includeContent as boolean;\n\n const docs = await this.discoverDocs(projectPath);\n const code = await this.discoverCode(projectPath);\n const allFiles = [...docs, ...code];\n const graph = await this.buildDependencyGraph(allFiles);\n const frameworks = await this.detectFrameworks(projectPath);\n\n // Build summary\n const docsByCategory: Record<string, number> = {};\n const codeByLanguage: Record<string, number> = {};\n\n for (const doc of docs) {\n docsByCategory[doc.category] = (docsByCategory[doc.category] || 0) + 1;\n }\n for (const file of code) {\n if (file.language) {\n codeByLanguage[file.language] = (codeByLanguage[file.language] || 0) + 1;\n }\n }\n\n const summary: DiscoverySummary = {\n totalDocs: docs.length,\n totalCode: code.length,\n docsByCategory,\n codeByLanguage,\n frameworks,\n };\n\n return { docs, code, graph, summary };\n }\n\n /**\n * Discover documentation files\n */\n async discoverDocs(projectPath: string): Promise<DiscoveredFile[]> {\n const docs: DiscoveredFile[] = [];\n await this.walkDirectory(projectPath, projectPath, docs, 'doc', 0);\n return docs;\n }\n\n /**\n * Discover code files\n */\n async discoverCode(projectPath: string): Promise<DiscoveredFile[]> {\n const code: DiscoveredFile[] = [];\n await this.walkDirectory(projectPath, projectPath, code, 'code', 0);\n return code;\n }\n\n /**\n * Build dependency graph from discovered files\n */\n async buildDependencyGraph(files: DiscoveredFile[]): Promise<DependencyGraph> {\n const nodes = new Map<string, GraphNode>();\n const edges: GraphEdge[] = [];\n\n // Create nodes\n for (const file of files) {\n nodes.set(file.relativePath, {\n id: file.relativePath,\n path: file.path,\n type: file.type,\n category: file.category,\n });\n }\n\n // Create edges based on imports/references\n for (const file of files) {\n if (file.type === 'code' && file.imports) {\n for (const imp of file.imports) {\n // Resolve import to relative path\n const targetPath = this.resolveImport(file.relativePath, imp);\n if (nodes.has(targetPath)) {\n edges.push({\n from: file.relativePath,\n to: targetPath,\n type: 'imports',\n });\n }\n }\n }\n }\n\n return { nodes, edges };\n }\n\n /**\n * Detect frameworks used in the project\n */\n async detectFrameworks(projectPath: string): Promise<string[]> {\n const detected: string[] = [];\n\n // Check package.json for dependencies\n const packageJsonPath = join(projectPath, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n for (const [framework, indicators] of Object.entries(FRAMEWORK_INDICATORS)) {\n for (const indicator of indicators) {\n if (allDeps[indicator]) {\n detected.push(framework);\n break;\n }\n }\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for framework-specific files\n for (const [framework, indicators] of Object.entries(FRAMEWORK_INDICATORS)) {\n if (detected.includes(framework)) continue;\n\n for (const indicator of indicators) {\n if (existsSync(join(projectPath, indicator))) {\n detected.push(framework);\n break;\n }\n }\n }\n\n // Check for Python frameworks\n const requirementsPath = join(projectPath, 'requirements.txt');\n if (existsSync(requirementsPath)) {\n try {\n const requirements = readFileSync(requirementsPath, 'utf-8').toLowerCase();\n if (requirements.includes('django')) detected.push('django');\n if (requirements.includes('flask')) detected.push('flask');\n if (requirements.includes('fastapi')) detected.push('fastapi');\n } catch {\n // Ignore\n }\n }\n\n return [...new Set(detected)];\n }\n\n // =========================================================================\n // Private Methods\n // =========================================================================\n\n private async walkDirectory(\n currentPath: string,\n projectRoot: string,\n files: DiscoveredFile[],\n targetType: 'doc' | 'code',\n depth: number\n ): Promise<void> {\n if (depth > this.maxDepth) return;\n if (!existsSync(currentPath)) return;\n\n const stat = statSync(currentPath);\n if (!stat.isDirectory()) return;\n\n const entries = readdirSync(currentPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relativePath = relative(projectRoot, fullPath);\n\n // Skip excluded paths\n if (EXCLUDE_PATHS.some((ex) => relativePath.includes(ex))) continue;\n\n if (entry.isDirectory()) {\n // Skip hidden directories (except .github)\n if (entry.name.startsWith('.') && entry.name !== '.github') continue;\n await this.walkDirectory(fullPath, projectRoot, files, targetType, depth + 1);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n const file = this.processFile(fullPath, projectRoot, ext, targetType);\n if (file) files.push(file);\n }\n }\n }\n\n private processFile(\n fullPath: string,\n projectRoot: string,\n ext: string,\n targetType: 'doc' | 'code'\n ): DiscoveredFile | null {\n try {\n const stat = statSync(fullPath);\n if (stat.size > this.maxFileSize) return null;\n\n const relativePath = relative(projectRoot, fullPath);\n const filename = basename(fullPath);\n\n // Check if it's a doc file\n if (targetType === 'doc') {\n if (!DOC_EXTENSIONS.includes(ext) && !SPEC_EXTENSIONS.includes(ext)) {\n return null;\n }\n // For spec files, only include API-related ones\n if (SPEC_EXTENSIONS.includes(ext)) {\n const name = filename.toLowerCase();\n if (!name.includes('openapi') && !name.includes('swagger') && !name.includes('api')) {\n return null;\n }\n }\n }\n\n // Check if it's a code file\n if (targetType === 'code') {\n if (!CODE_EXTENSIONS[ext]) return null;\n }\n\n const content = this.includeContent ? readFileSync(fullPath, 'utf-8') : undefined;\n const hash = createHash('md5').update(content || fullPath).digest('hex');\n\n const file: DiscoveredFile = {\n path: fullPath,\n relativePath,\n type: targetType,\n category: this.categorizeFile(filename, relativePath, targetType),\n size: stat.size,\n hash,\n };\n\n if (targetType === 'code') {\n file.language = CODE_EXTENSIONS[ext];\n if (content) {\n file.imports = this.extractImports(content, file.language!);\n file.exports = this.extractExports(content, file.language!);\n }\n }\n\n if (this.includeContent) {\n file.content = content;\n }\n\n return file;\n } catch {\n return null;\n }\n }\n\n private categorizeFile(filename: string, relativePath: string, type: 'doc' | 'code'): string {\n const lower = filename.toLowerCase();\n const pathLower = relativePath.toLowerCase();\n const categories = type === 'doc' ? DOC_CATEGORIES : CODE_CATEGORIES;\n\n for (const [category, patterns] of Object.entries(categories)) {\n for (const pattern of patterns) {\n if (pattern.test(lower) || pattern.test(pathLower)) {\n return category;\n }\n }\n }\n\n return 'other';\n }\n\n private extractImports(content: string, language: string): string[] {\n const imports: string[] = [];\n\n if (language === 'typescript' || language === 'javascript') {\n // ES6 imports\n const es6Regex = /import\\s+(?:(?:\\{[^}]*\\}|\\*\\s+as\\s+\\w+|\\w+)(?:\\s*,\\s*(?:\\{[^}]*\\}|\\*\\s+as\\s+\\w+|\\w+))*\\s+from\\s+)?['\"]([^'\"]+)['\"]/g;\n let match;\n while ((match = es6Regex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n // CommonJS requires\n const requireRegex = /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n while ((match = requireRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n } else if (language === 'python') {\n // Python imports\n const importRegex = /^(?:from\\s+(\\S+)\\s+)?import\\s+(.+)$/gm;\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n imports.push(match[1] || match[2].split(',')[0].trim());\n }\n }\n\n return [...new Set(imports)];\n }\n\n private extractExports(content: string, language: string): string[] {\n const exports: string[] = [];\n\n if (language === 'typescript' || language === 'javascript') {\n // Named exports\n const namedExportRegex = /export\\s+(?:const|let|var|function|class|interface|type|enum)\\s+(\\w+)/g;\n let match;\n while ((match = namedExportRegex.exec(content)) !== null) {\n exports.push(match[1]);\n }\n\n // Export statements\n const exportStatementRegex = /export\\s+\\{\\s*([^}]+)\\s*\\}/g;\n while ((match = exportStatementRegex.exec(content)) !== null) {\n const items = match[1].split(',').map((s) => s.trim().split(/\\s+as\\s+/)[0]);\n exports.push(...items);\n }\n\n // Default export\n if (/export\\s+default/.test(content)) {\n exports.push('default');\n }\n }\n\n return [...new Set(exports)];\n }\n\n private resolveImport(fromPath: string, importPath: string): string {\n // Skip external packages\n if (!importPath.startsWith('.') && !importPath.startsWith('/')) {\n return importPath;\n }\n\n // Simple resolution (doesn't handle all edge cases)\n const fromDir = fromPath.split('/').slice(0, -1).join('/');\n const parts = importPath.split('/');\n const resultParts = fromDir ? fromDir.split('/') : [];\n\n for (const part of parts) {\n if (part === '.') continue;\n if (part === '..') {\n resultParts.pop();\n } else {\n resultParts.push(part);\n }\n }\n\n let result = resultParts.join('/');\n\n // Add common extensions if missing\n if (!extname(result)) {\n const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];\n for (const ext of extensions) {\n const candidate = result + ext;\n // In a real implementation, we'd check if the file exists\n // For now, just return the base path\n }\n }\n\n return result;\n }\n}\n","/**\n * Analyzer Agent\n *\n * Responsible for:\n * - Extracting requirements from documentation\n * - Extracting features/capabilities from code\n * - Mapping requirements to code implementations\n * - Detecting potential drift between docs and code\n */\n\nimport { createJsonCompletion } from '../ai/client.js';\nimport { BaseAgent } from './base-agent.js';\nimport {\n TaskMessage,\n ResultMessage,\n Requirement,\n RequirementCategory,\n RequirementMapping,\n AnalysisResult,\n} from './types.js';\nimport {\n parseFile,\n astToPromptFormat,\n CodeAST,\n FileMetadata,\n calculateTokenSavings,\n} from '../ast/index.js';\n\n// ============================================================================\n// Analyzer Agent\n// ============================================================================\n\nexport class AnalyzerAgent extends BaseAgent {\n constructor() {\n super('analyzer');\n }\n\n async execute(task: TaskMessage): Promise<ResultMessage> {\n const startTime = Date.now();\n this.status = 'executing';\n this.emitEvent('agent:task_started', { taskId: task.payload.taskId });\n\n try {\n const { taskType, inputs } = task.payload;\n let result: unknown;\n let tokensUsed = { input: 0, output: 0 };\n\n switch (taskType) {\n case 'extract_requirements': {\n const extracted = await this.extractRequirementsFromDocs(\n inputs.content as string,\n inputs.framework as string | undefined\n );\n result = extracted.requirements;\n tokensUsed = extracted.tokensUsed;\n break;\n }\n case 'extract_features': {\n const extracted = await this.extractFeaturesFromCode(\n inputs.content as string,\n inputs.framework as string | undefined\n );\n result = extracted.features;\n tokensUsed = extracted.tokensUsed;\n break;\n }\n case 'map_requirements': {\n const mapped = await this.mapRequirements(\n inputs.docRequirements as Requirement[],\n inputs.codeFeatures as Requirement[],\n inputs.docsContent as string,\n inputs.codeContent as string\n );\n result = mapped;\n tokensUsed = mapped.tokensUsed;\n break;\n }\n case 'analyze_full': {\n const analysis = await this.fullAnalysis(\n inputs.docsContent as string,\n inputs.codeContent as string,\n inputs.framework as string | undefined,\n inputs.codeFiles as Array<{ content: string; path: string; relativePath: string }> | undefined\n );\n result = analysis;\n tokensUsed = analysis.tokensUsed;\n break;\n }\n case 'extract_features_ast': {\n const extracted = await this.extractFeaturesFromAST(\n inputs.codeFiles as Array<{ content: string; path: string; relativePath: string }>,\n inputs.framework as string | undefined\n );\n result = extracted.features;\n tokensUsed = extracted.tokensUsed;\n break;\n }\n default:\n throw new Error(`Unknown task type: ${taskType}`);\n }\n\n const executionTime = Date.now() - startTime;\n this.addTokens(tokensUsed.input, tokensUsed.output);\n this.tasksCompleted++;\n this.status = 'complete';\n this.emitEvent('agent:task_completed', { taskId: task.payload.taskId, success: true });\n\n // Calculate confidence based on completeness of extraction\n const confidence = this.calculateConfidence(result);\n\n return this.createSuccessResult(\n task.payload.taskId,\n result,\n confidence,\n tokensUsed,\n executionTime\n );\n } catch (err) {\n const executionTime = Date.now() - startTime;\n const error = err instanceof Error ? err.message : 'Unknown error';\n this.status = 'error';\n\n return this.createErrorResult(task.payload.taskId, error, executionTime);\n }\n }\n\n /**\n * Extract requirements from documentation\n */\n async extractRequirementsFromDocs(\n docsContent: string,\n framework?: string\n ): Promise<{ requirements: Requirement[]; tokensUsed: { input: number; output: number } }> {\n const frameworkContext = framework\n ? `\\nThis project uses ${framework}. Consider framework-specific requirements and conventions.`\n : '';\n\n const systemPrompt = `You are a senior requirements analyst specializing in software documentation.\nYour task is to extract ALL requirements from the provided documentation.${frameworkContext}\n\nCRITICAL: Each requirement MUST have a detailed, actionable \"description\" field.\nEnterprise developers will use these descriptions to understand exactly what needs to be built.\n\nOutput format:\n{\n \"requirements\": [\n {\n \"id\": \"R-001\",\n \"description\": \"User authentication via email/password with JWT tokens - Users must be able to sign up and log in using email and password. System issues JWT tokens with 1-hour expiry for session management.\",\n \"category\": \"security\",\n \"priority\": \"high\",\n \"sourceFile\": \"docs/PRD.md\",\n \"sourceLine\": 45\n }\n ]\n}\n\nCategories: feature, api, security, performance, ui, data, integration, infrastructure\n\nExtraction guidelines:\n- Extract EXPLICIT requirements (\"must\", \"should\", \"will\", \"shall\")\n- Extract IMPLICIT requirements from feature descriptions\n- Include API contracts (endpoints, methods, parameters, responses)\n- Include security requirements (auth, authorization, encryption)\n- Include performance requirements (limits, quotas, SLAs)\n- Include data requirements (formats, validation, storage)\n- Prioritize based on: critical > high > medium > low\n\nDescription guidelines:\n- Write 1-3 sentences fully explaining the requirement\n- Include specific values (limits, formats, behaviors)\n- Be concrete enough for implementation\n- Include acceptance criteria when evident`;\n\n const userMessage = `Extract ALL requirements from this documentation:\n\n${docsContent.substring(0, 80000)}`;\n\n const result = await createJsonCompletion<{ requirements: Requirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Ensure all requirements have required fields\n const requirements = reqs.map((r, idx) => ({\n id: r.id || `R-${String(idx + 1).padStart(3, '0')}`,\n description: r.description || 'No description provided',\n category: (r.category || 'feature') as RequirementCategory,\n source: 'docs' as const,\n sourceFile: r.sourceFile,\n sourceLine: r.sourceLine,\n priority: r.priority,\n }));\n\n return {\n requirements,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Extract features/implementations from code\n */\n async extractFeaturesFromCode(\n codeContent: string,\n framework?: string\n ): Promise<{ features: Requirement[]; tokensUsed: { input: number; output: number } }> {\n const frameworkContext = framework\n ? `\\nThis project uses ${framework}. Apply framework-specific analysis patterns.`\n : '';\n\n const systemPrompt = `You are a senior code analyst specializing in reverse engineering.\nYour task is to extract ALL implemented features from the provided code.${frameworkContext}\n\nCRITICAL: Each feature MUST have a detailed \"description\" explaining what the code actually does.\nEnterprise developers need to understand the exact implementation.\n\nOutput format:\n{\n \"requirements\": [\n {\n \"id\": \"F-001\",\n \"description\": \"JWT authentication with 1-hour expiry - Login endpoint at /api/auth/login accepts POST with email/password, validates credentials, returns JWT access token and httpOnly refresh token cookie.\",\n \"category\": \"security\",\n \"sourceFile\": \"src/auth/login.ts\",\n \"sourceLine\": 12\n }\n ]\n}\n\nCategories: feature, api, security, performance, ui, data, integration, infrastructure\n\nExtraction guidelines:\n- Extract API endpoints with actual behaviors (methods, params, responses)\n- Extract authentication/authorization implementations\n- Extract rate limiting, quotas, constraints (with actual values!)\n- Extract database operations and data models\n- Extract integration points (external APIs, services)\n- Extract validation rules and error handling\n- Extract business logic and workflows\n\nDescription guidelines:\n- Write 1-3 sentences explaining WHAT the code does\n- Include concrete values (endpoints, limits, formats)\n- Be specific enough for documentation\n- Include actual implementation details found in code`;\n\n const userMessage = `Extract ALL implemented features from this code:\n\n${codeContent.substring(0, 80000)}`;\n\n const result = await createJsonCompletion<{ requirements: Requirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Ensure all features have required fields\n const features = reqs.map((r, idx) => ({\n id: r.id || `F-${String(idx + 1).padStart(3, '0')}`,\n description: r.description || 'No description provided',\n category: (r.category || 'feature') as RequirementCategory,\n source: 'code' as const,\n sourceFile: r.sourceFile,\n sourceLine: r.sourceLine,\n }));\n\n return {\n features,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Extract features using AST-based analysis (more efficient)\n * Reduces token usage by 50-70% while improving accuracy\n */\n async extractFeaturesFromAST(\n codeFiles: Array<{ content: string; path: string; relativePath: string }>,\n framework?: string\n ): Promise<{ features: Requirement[]; tokensUsed: { input: number; output: number }; tokensSaved: number }> {\n // Parse all files into AST\n const astResults: CodeAST[] = [];\n let totalRawLength = 0;\n\n for (const file of codeFiles) {\n totalRawLength += file.content.length;\n\n const metadata: FileMetadata = {\n path: file.path,\n relativePath: file.relativePath,\n language: this.detectLanguage(file.path),\n size: file.content.length,\n };\n\n try {\n const ast = await parseFile(file.content, metadata);\n astResults.push(ast);\n } catch (err) {\n // Skip files that fail to parse\n console.warn(`Failed to parse ${file.path}:`, err);\n }\n }\n\n // Convert ASTs to compact prompt format\n const astPrompts = astResults\n .filter((ast) => ast.functions.length > 0 || ast.routes.length > 0 || ast.classes.length > 0)\n .map((ast) => astToPromptFormat(ast))\n .join('\\n---\\n');\n\n const { savings: tokensSaved } = calculateTokenSavings(totalRawLength, astPrompts.length);\n\n const frameworkContext = framework\n ? `\\nThis project uses ${framework}. Apply framework-specific analysis patterns.`\n : '';\n\n const systemPrompt = `You are a senior code analyst specializing in reverse engineering.\nYou are provided with STRUCTURED AST (Abstract Syntax Tree) representations of code files.\nThis format shows functions, routes, types, and constants in a compact format.${frameworkContext}\n\nCRITICAL: Each feature MUST have a detailed \"description\" explaining what the code actually does.\nUse the structured information (routes, params, types) to create precise descriptions.\n\nOutput format:\n{\n \"requirements\": [\n {\n \"id\": \"F-001\",\n \"description\": \"JWT authentication with 1-hour expiry - Login endpoint at POST /api/auth/login accepts email/password, validates credentials, returns JWT access token.\",\n \"category\": \"security\",\n \"sourceFile\": \"src/auth/login.ts\",\n \"sourceLine\": 12\n }\n ]\n}\n\nCategories: feature, api, security, performance, ui, data, integration, infrastructure\n\nFrom the AST, extract:\n- API routes with their methods, paths, params, and middleware\n- Exported functions with their signatures and purposes\n- Constants especially config values, limits, and feature flags\n- Type definitions that define data structures\n- Classes and their public methods\n\nFocus on extracting ACTUAL VALUES from constants (rate limits, timeouts, etc.)`;\n\n const userMessage = `Extract ALL implemented features from this AST representation:\n\n${astPrompts.substring(0, 100000)}`;\n\n const result = await createJsonCompletion<{ requirements: Requirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n const features = reqs.map((r, idx) => ({\n id: r.id || `F-${String(idx + 1).padStart(3, '0')}`,\n description: r.description || 'No description provided',\n category: (r.category || 'feature') as RequirementCategory,\n source: 'code' as const,\n sourceFile: r.sourceFile,\n sourceLine: r.sourceLine,\n }));\n\n this.emitEvent('analyzer:ast_extraction', {\n filesProcessed: astResults.length,\n featuresFound: features.length,\n tokensSaved,\n });\n\n return {\n features,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n tokensSaved,\n };\n }\n\n /**\n * Detect language from file extension\n */\n private detectLanguage(filePath: string): FileMetadata['language'] {\n if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) return 'typescript';\n if (filePath.endsWith('.js') || filePath.endsWith('.jsx')) return 'javascript';\n if (filePath.endsWith('.py')) return 'python';\n if (filePath.endsWith('.go')) return 'go';\n if (filePath.endsWith('.java')) return 'java';\n if (filePath.endsWith('.rs')) return 'rust';\n return 'typescript'; // Default\n }\n\n /**\n * Map documentation requirements to code implementations\n */\n async mapRequirements(\n docRequirements: Requirement[],\n codeFeatures: Requirement[],\n docsContent: string,\n codeContent: string\n ): Promise<{\n mappings: RequirementMapping[];\n unmappedDocs: Requirement[];\n unmappedCode: Requirement[];\n tokensUsed: { input: number; output: number };\n }> {\n const systemPrompt = `You are a specification verification expert.\nYour task is to map documentation requirements to code implementations.\n\nFor each requirement, find the corresponding code feature (if any) and score the match.\n\nOutput format:\n{\n \"mappings\": [\n {\n \"docRequirementId\": \"R-001\",\n \"codeFeatureId\": \"F-003\",\n \"matchScore\": 85,\n \"evidence\": [\n \"Both specify JWT authentication\",\n \"Token expiry matches: 1 hour\"\n ]\n }\n ],\n \"unmappedDocRequirements\": [\"R-005\", \"R-008\"],\n \"unmappedCodeFeatures\": [\"F-012\"]\n}\n\nMatch score guidelines:\n- 90-100: Exact match, implementation fully satisfies requirement\n- 70-89: Strong match, minor differences or missing details\n- 50-69: Partial match, significant differences\n- Below 50: Weak match, consider unmapped`;\n\n const docsReqJson = JSON.stringify(docRequirements, null, 2);\n const codeFeatJson = JSON.stringify(codeFeatures, null, 2);\n\n const userMessage = `Map these documentation requirements to code features:\n\n## DOCUMENTATION REQUIREMENTS:\n${docsReqJson}\n\n## CODE FEATURES:\n${codeFeatJson}\n\n## DOCUMENTATION CONTEXT:\n${docsContent.substring(0, 20000)}\n\n## CODE CONTEXT:\n${codeContent.substring(0, 20000)}`;\n\n const result = await createJsonCompletion<{\n mappings: RequirementMapping[];\n unmappedDocRequirements: string[];\n unmappedCodeFeatures: string[];\n }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 8192,\n });\n\n const data = result.data;\n const mappings = data.mappings || [];\n const unmappedDocIds = new Set(data.unmappedDocRequirements || []);\n const unmappedCodeIds = new Set(data.unmappedCodeFeatures || []);\n\n // Also mark as unmapped any that weren't in mappings\n const mappedDocIds = new Set(mappings.map((m) => m.docRequirementId));\n const mappedCodeIds = new Set(mappings.map((m) => m.codeFeatureId).filter(Boolean));\n\n for (const req of docRequirements) {\n if (!mappedDocIds.has(req.id)) {\n unmappedDocIds.add(req.id);\n }\n }\n for (const feat of codeFeatures) {\n if (!mappedCodeIds.has(feat.id)) {\n unmappedCodeIds.add(feat.id);\n }\n }\n\n return {\n mappings,\n unmappedDocs: docRequirements.filter((r) => unmappedDocIds.has(r.id)),\n unmappedCode: codeFeatures.filter((f) => unmappedCodeIds.has(f.id)),\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Full analysis: extract and map in one pipeline\n * Supports both raw code and AST-based analysis\n */\n async fullAnalysis(\n docsContent: string,\n codeContent: string,\n framework?: string,\n codeFiles?: Array<{ content: string; path: string; relativePath: string }>\n ): Promise<AnalysisResult & { tokensUsed: { input: number; output: number }; tokensSaved?: number }> {\n // Step 1: Extract requirements from docs\n const docsResult = await this.extractRequirementsFromDocs(docsContent, framework);\n\n // Step 2: Extract features from code (use AST if files provided)\n let codeResult: { features: Requirement[]; tokensUsed: { input: number; output: number }; tokensSaved?: number };\n\n if (codeFiles && codeFiles.length > 0) {\n // Use AST-based extraction for better accuracy and lower token usage\n this.emitEvent('analyzer:using_ast', { fileCount: codeFiles.length });\n const astResult = await this.extractFeaturesFromAST(codeFiles, framework);\n codeResult = {\n features: astResult.features,\n tokensUsed: astResult.tokensUsed,\n tokensSaved: astResult.tokensSaved,\n };\n } else {\n // Fallback to raw code extraction\n codeResult = await this.extractFeaturesFromCode(codeContent, framework);\n }\n\n // Step 3: Map them together\n const mappingResult = await this.mapRequirements(\n docsResult.requirements,\n codeResult.features,\n docsContent,\n codeContent\n );\n\n // Combine all requirements\n const allRequirements = [\n ...docsResult.requirements,\n ...codeResult.features.map((f) => ({ ...f, source: 'code' as const })),\n ];\n\n // Calculate overall confidence\n const totalMapped = mappingResult.mappings.length;\n const totalReqs = docsResult.requirements.length + codeResult.features.length;\n const avgMatchScore =\n mappingResult.mappings.length > 0\n ? mappingResult.mappings.reduce((sum, m) => sum + m.matchScore, 0) / mappingResult.mappings.length\n : 0;\n const confidence = Math.round((totalMapped / Math.max(totalReqs, 1)) * avgMatchScore);\n\n const totalTokens = {\n input: docsResult.tokensUsed.input + codeResult.tokensUsed.input + mappingResult.tokensUsed.input,\n output: docsResult.tokensUsed.output + codeResult.tokensUsed.output + mappingResult.tokensUsed.output,\n };\n\n return {\n requirements: allRequirements,\n mappings: mappingResult.mappings,\n confidence,\n tokensUsed: totalTokens,\n tokensSaved: codeResult.tokensSaved,\n };\n }\n\n /**\n * Calculate confidence score for results\n */\n private calculateConfidence(result: unknown): number {\n if (!result) return 0;\n\n if (Array.isArray(result)) {\n // For requirement arrays, check completeness\n const reqs = result as Requirement[];\n if (reqs.length === 0) return 50;\n\n const hasDescriptions = reqs.filter((r) => r.description && r.description.length > 20).length;\n const hasCategories = reqs.filter((r) => r.category).length;\n const hasSources = reqs.filter((r) => r.sourceFile).length;\n\n const score =\n 50 +\n (hasDescriptions / reqs.length) * 20 +\n (hasCategories / reqs.length) * 15 +\n (hasSources / reqs.length) * 15;\n\n return Math.min(100, Math.round(score));\n }\n\n // For analysis results\n const analysis = result as AnalysisResult;\n if (analysis.confidence !== undefined) {\n return analysis.confidence;\n }\n\n return 75; // Default confidence\n }\n}\n","/**\n * Knowledge Base Types\n *\n * Type definitions for the VasperaPM verification knowledge base\n * and network effects system.\n */\n\n// ============================================================================\n// Core Types\n// ============================================================================\n\nexport type DriftSeverity = 'critical' | 'high' | 'medium' | 'low';\nexport type DriftCategory = 'api' | 'security' | 'performance' | 'data' | 'ui' | 'integration' | 'infrastructure' | 'other';\nexport type VerificationStatus = 'verified' | 'drift' | 'undocumented' | 'unimplemented';\nexport type FeedbackSource = 'implicit' | 'explicit' | 'correction';\nexport type ProjectSize = 'small' | 'medium' | 'large' | 'enterprise';\n\n// ============================================================================\n// Drift Patterns\n// ============================================================================\n\nexport interface DriftPattern {\n id: string;\n patternKey: string;\n description: string;\n category: DriftCategory;\n severity: DriftSeverity;\n frameworks: string[];\n languages: string[];\n frequency: number;\n falsePositiveRate: number;\n acceptanceRate: number;\n sampleSize: number;\n autoFixSuggestion?: string;\n exampleDocPattern?: string;\n exampleCodePattern?: string;\n detectionHint?: string;\n createdAt: Date;\n updatedAt: Date;\n lastSeenAt: Date;\n}\n\n// ============================================================================\n// Framework Rules\n// ============================================================================\n\nexport interface FrameworkRule {\n id: string;\n framework: string;\n versionPattern?: string;\n ruleKey: string;\n ruleType: 'expected_doc' | 'common_drift' | 'hint' | 'verification_skip';\n ruleData: ExpectedDoc | CommonDriftRule | HintRule | Record<string, unknown>;\n confidence: number;\n sampleSize: number;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface ExpectedDoc {\n name: string;\n patterns: string[];\n requiredSections: string[];\n codePatterns?: string[];\n}\n\nexport interface CommonDriftRule {\n pattern: string;\n frequency: 'rare' | 'occasional' | 'common' | 'very_common';\n}\n\nexport interface HintRule {\n hint: string;\n}\n\n// ============================================================================\n// Accuracy Feedback\n// ============================================================================\n\nexport interface AccuracyFeedback {\n id: string;\n projectHash: string;\n patternId?: string;\n ourPrediction: VerificationStatus;\n actualStatus?: VerificationStatus;\n context: FeedbackContext;\n feedbackSource: FeedbackSource;\n userReason?: string;\n createdAt: Date;\n}\n\nexport interface FeedbackContext {\n framework?: string;\n language?: string;\n filePatternHash?: string;\n driftType?: string;\n category?: DriftCategory;\n}\n\n// ============================================================================\n// Anonymized Analysis Report\n// ============================================================================\n\nexport interface AnonymizedAnalysisReport {\n id?: string;\n projectHash: string;\n analysisHash: string;\n frameworks: string[];\n languages: string[];\n projectSize: ProjectSize;\n totalRequirements: number;\n verifiedCount: number;\n driftCount: number;\n undocumentedCount: number;\n unimplementedCount: number;\n driftTypes: AnonymizedDrift[];\n analysisTimeMs?: number;\n tokensUsed?: number;\n debatesTriggered?: number;\n debatesOverturned?: number;\n overallConfidence?: number;\n createdAt?: Date;\n}\n\nexport interface AnonymizedDrift {\n type: string;\n category: DriftCategory;\n severity: DriftSeverity;\n filePatternHash: string;\n wasAccepted: boolean;\n}\n\n// ============================================================================\n// Knowledge Base Statistics\n// ============================================================================\n\nexport interface KnowledgeBaseStats {\n totalAnalyses: number;\n uniqueProjects: number;\n totalRequirementsVerified: number;\n totalDriftPatterns: number;\n totalDriftObservations: number;\n totalFrameworkRules: number;\n frameworksCovered: number;\n totalFeedbackItems: number;\n correctPredictions: number;\n lastAnalysisAt?: Date;\n lastPatternUpdateAt?: Date;\n}\n\n// ============================================================================\n// Pattern Matching Results\n// ============================================================================\n\nexport interface PatternMatch {\n pattern: DriftPattern;\n matchScore: number;\n reasons: string[];\n}\n\nexport interface FrameworkContext {\n frameworks: string[];\n languages: string[];\n patterns: DriftPattern[];\n rules: FrameworkRule[];\n}\n\n// ============================================================================\n// Collector Configuration\n// ============================================================================\n\nexport interface CollectorConfig {\n /** Whether to enable pattern collection */\n enabled: boolean;\n /** Minimum sample size before contributing patterns */\n minSampleSize: number;\n /** API endpoint for cloud sync (optional) */\n cloudEndpoint?: string;\n /** Whether to collect anonymized reports */\n collectReports: boolean;\n /** Whether to collect feedback */\n collectFeedback: boolean;\n}\n\nexport const DEFAULT_COLLECTOR_CONFIG: CollectorConfig = {\n enabled: true,\n minSampleSize: 1,\n collectReports: true,\n collectFeedback: true,\n};\n","/**\n * Anonymizer Utility\n *\n * Ensures all data collected for the knowledge base is properly\n * anonymized with no PII, no code, and no identifiable information.\n */\n\nimport { createHash } from 'crypto';\nimport {\n AnonymizedAnalysisReport,\n AnonymizedDrift,\n DriftCategory,\n DriftSeverity,\n ProjectSize,\n FeedbackContext,\n} from './types.js';\n\n// ============================================================================\n// Hash Functions\n// ============================================================================\n\n/**\n * Create a non-reversible hash of a project identifier\n * Uses SHA-256 with a salt to prevent rainbow table attacks\n */\nexport function hashProject(projectPath: string, organizationHint?: string): string {\n const input = `${projectPath}:${organizationHint || 'unknown'}`;\n return createHash('sha256').update(input).digest('hex').substring(0, 32);\n}\n\n/**\n * Create a hash for a specific analysis run\n */\nexport function hashAnalysis(projectHash: string, timestamp: Date): string {\n const input = `${projectHash}:${timestamp.toISOString()}`;\n return createHash('sha256').update(input).digest('hex').substring(0, 16);\n}\n\n/**\n * Hash a file pattern to prevent leaking file names\n */\nexport function hashFilePattern(filePath: string): string {\n // Extract just the pattern, not the full path\n const parts = filePath.split('/');\n const pattern = parts.slice(-2).join('/'); // Last 2 segments only\n return createHash('md5').update(pattern).digest('hex').substring(0, 12);\n}\n\n// ============================================================================\n// Classification Functions\n// ============================================================================\n\n/**\n * Determine project size from file counts\n */\nexport function classifyProjectSize(docsCount: number, codeCount: number): ProjectSize {\n const total = docsCount + codeCount;\n\n if (total < 20) return 'small';\n if (total < 100) return 'medium';\n if (total < 500) return 'large';\n return 'enterprise';\n}\n\n/**\n * Extract drift type from a drift description without leaking specifics\n */\nexport function extractDriftType(description: string): string {\n // Common patterns to look for\n const patterns: Record<string, RegExp> = {\n rate_limit_mismatch: /rate.?limit|throttl|quota/i,\n auth_drift: /auth|login|jwt|session|token/i,\n api_schema_mismatch: /schema|openapi|swagger|validation/i,\n error_codes_drift: /error.?code|exception|status/i,\n env_vars_missing: /env|environment|config/i,\n pricing_drift: /price|pricing|tier|subscription|billing/i,\n pagination_missing: /pagination|page|limit|offset|cursor/i,\n webhook_missing: /webhook|event|callback/i,\n security_headers: /security|header|cors|csp|helmet/i,\n database_drift: /database|schema|model|table|column/i,\n performance_drift: /performance|latency|timeout|cache/i,\n permission_drift: /permission|role|access|rbac/i,\n };\n\n for (const [type, regex] of Object.entries(patterns)) {\n if (regex.test(description)) {\n return type;\n }\n }\n\n return 'generic_drift';\n}\n\n// ============================================================================\n// Anonymization Functions\n// ============================================================================\n\n/**\n * Create an anonymized analysis report from verification results\n */\nexport function anonymizeAnalysisReport(\n projectPath: string,\n frameworks: string[],\n languages: string[],\n results: {\n total: number;\n verified: number;\n drift: number;\n undocumented: number;\n unimplemented: number;\n driftItems: Array<{\n description: string;\n category?: string;\n severity?: string;\n sourceFile?: string;\n accepted?: boolean;\n }>;\n analysisTimeMs?: number;\n tokensUsed?: number;\n debatesTriggered?: number;\n debatesOverturned?: number;\n overallConfidence?: number;\n },\n docsCount: number,\n codeCount: number\n): AnonymizedAnalysisReport {\n const projectHash = hashProject(projectPath);\n const analysisHash = hashAnalysis(projectHash, new Date());\n\n // Anonymize drift items\n const driftTypes: AnonymizedDrift[] = results.driftItems.map((item) => ({\n type: extractDriftType(item.description),\n category: (item.category || 'other') as DriftCategory,\n severity: (item.severity || 'medium') as DriftSeverity,\n filePatternHash: item.sourceFile ? hashFilePattern(item.sourceFile) : 'unknown',\n wasAccepted: item.accepted ?? true,\n }));\n\n return {\n projectHash,\n analysisHash,\n frameworks,\n languages,\n projectSize: classifyProjectSize(docsCount, codeCount),\n totalRequirements: results.total,\n verifiedCount: results.verified,\n driftCount: results.drift,\n undocumentedCount: results.undocumented,\n unimplementedCount: results.unimplemented,\n driftTypes,\n analysisTimeMs: results.analysisTimeMs,\n tokensUsed: results.tokensUsed,\n debatesTriggered: results.debatesTriggered,\n debatesOverturned: results.debatesOverturned,\n overallConfidence: results.overallConfidence,\n };\n}\n\n/**\n * Create anonymized feedback context\n */\nexport function anonymizeFeedbackContext(\n framework?: string,\n language?: string,\n filePath?: string,\n driftType?: string,\n category?: string\n): FeedbackContext {\n return {\n framework,\n language,\n filePatternHash: filePath ? hashFilePattern(filePath) : undefined,\n driftType: driftType ? extractDriftType(driftType) : undefined,\n category: category as DriftCategory | undefined,\n };\n}\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Ensure a string contains no PII\n */\nexport function containsPII(text: string): boolean {\n // Check for common PII patterns\n const piiPatterns = [\n // Email addresses\n /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/,\n // API keys (common formats)\n /sk[-_][a-zA-Z0-9]{20,}/i,\n /api[-_]?key\\s*[:=]\\s*[\"']?[a-zA-Z0-9-_]{16,}/i,\n // Secrets\n /secret\\s*[:=]\\s*[\"']?[a-zA-Z0-9-_]{8,}/i,\n /password\\s*[:=]\\s*[\"']?[^\\s\"']{4,}/i,\n // AWS keys\n /AKIA[0-9A-Z]{16}/,\n // GitHub tokens\n /gh[pousr]_[A-Za-z0-9_]{36,}/,\n // Private keys\n /-----BEGIN\\s+(RSA\\s+)?PRIVATE\\s+KEY-----/,\n // IP addresses (internal)\n /\\b(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)\\d{1,3}\\.\\d{1,3}\\b/,\n // UUIDs that might be user IDs\n /user[-_]?id\\s*[:=]\\s*[\"']?[a-f0-9-]{36}/i,\n ];\n\n for (const pattern of piiPatterns) {\n if (pattern.test(text)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Sanitize a string by removing potential PII\n */\nexport function sanitize(text: string): string {\n if (!text) return '';\n\n let sanitized = text;\n\n // Remove emails\n sanitized = sanitized.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g, '[EMAIL]');\n\n // Remove API keys\n sanitized = sanitized.replace(/sk[-_][a-zA-Z0-9]{20,}/gi, '[API_KEY]');\n\n // Remove secrets\n sanitized = sanitized.replace(/secret\\s*[:=]\\s*[\"']?[a-zA-Z0-9-_]{8,}/gi, 'secret: [REDACTED]');\n\n // Remove file paths (full paths)\n sanitized = sanitized.replace(/\\/Users\\/[a-zA-Z0-9_-]+\\//g, '/[USER]/');\n sanitized = sanitized.replace(/C:\\\\Users\\\\[a-zA-Z0-9_-]+\\\\/gi, 'C:\\\\[USER]\\\\');\n sanitized = sanitized.replace(/\\/home\\/[a-zA-Z0-9_-]+\\//g, '/home/[USER]/');\n\n return sanitized;\n}\n\n/**\n * Validate an anonymized report has no PII\n */\nexport function validateAnonymizedReport(report: AnonymizedAnalysisReport): {\n valid: boolean;\n issues: string[];\n} {\n const issues: string[] = [];\n\n // Check that hashes are proper lengths\n if (report.projectHash.length !== 32) {\n issues.push('Project hash is wrong length');\n }\n\n if (report.analysisHash.length !== 16) {\n issues.push('Analysis hash is wrong length');\n }\n\n // Check that no drift descriptions contain PII\n for (const drift of report.driftTypes) {\n if (containsPII(drift.type)) {\n issues.push(`Drift type contains potential PII: ${drift.type.substring(0, 20)}`);\n }\n }\n\n // Check frameworks and languages are generic\n const allowedFrameworks = new Set([\n 'nextjs', 'react', 'vue', 'angular', 'svelte',\n 'express', 'fastify', 'hono', 'koa', 'nestjs',\n 'django', 'flask', 'fastapi', 'rails',\n 'spring', 'go', 'gin', 'echo',\n 'tailwind', 'bootstrap', 'material-ui',\n 'prisma', 'drizzle', 'typeorm', 'sequelize',\n ]);\n\n for (const fw of report.frameworks) {\n if (!allowedFrameworks.has(fw.toLowerCase())) {\n issues.push(`Unknown framework may contain custom name: ${fw}`);\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n","/**\n * Pattern Collector\n *\n * Collects anonymized patterns from verification runs and\n * optionally syncs them to the cloud for network effects.\n */\n\nimport { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport {\n AnonymizedAnalysisReport,\n DriftPattern,\n FrameworkRule,\n AccuracyFeedback,\n CollectorConfig,\n DEFAULT_COLLECTOR_CONFIG,\n DriftCategory,\n DriftSeverity,\n VerificationStatus,\n FeedbackSource,\n} from './types.js';\nimport {\n anonymizeAnalysisReport,\n anonymizeFeedbackContext,\n validateAnonymizedReport,\n hashProject,\n extractDriftType,\n} from './anonymizer.js';\n\n// ============================================================================\n// Local Storage\n// ============================================================================\n\nconst STORAGE_DIR = join(homedir(), '.vasperapm', 'knowledge-base');\nconst PATTERNS_FILE = join(STORAGE_DIR, 'patterns.json');\nconst REPORTS_FILE = join(STORAGE_DIR, 'reports.json');\nconst FEEDBACK_FILE = join(STORAGE_DIR, 'feedback.json');\n\nfunction ensureStorageDir(): void {\n if (!existsSync(STORAGE_DIR)) {\n mkdirSync(STORAGE_DIR, { recursive: true });\n }\n}\n\n// ============================================================================\n// Pattern Collector Class\n// ============================================================================\n\nexport class PatternCollector {\n private config: CollectorConfig;\n private localPatterns: Map<string, DriftPattern> = new Map();\n private localReports: AnonymizedAnalysisReport[] = [];\n private localFeedback: AccuracyFeedback[] = [];\n\n constructor(config: Partial<CollectorConfig> = {}) {\n this.config = { ...DEFAULT_COLLECTOR_CONFIG, ...config };\n this.loadLocalData();\n }\n\n // ==========================================================================\n // Data Loading\n // ==========================================================================\n\n private loadLocalData(): void {\n ensureStorageDir();\n\n // Load patterns\n if (existsSync(PATTERNS_FILE)) {\n try {\n const data = JSON.parse(readFileSync(PATTERNS_FILE, 'utf-8'));\n for (const pattern of data.patterns || []) {\n this.localPatterns.set(pattern.patternKey, pattern);\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Load reports\n if (existsSync(REPORTS_FILE)) {\n try {\n const data = JSON.parse(readFileSync(REPORTS_FILE, 'utf-8'));\n this.localReports = data.reports || [];\n } catch {\n // Ignore parse errors\n }\n }\n\n // Load feedback\n if (existsSync(FEEDBACK_FILE)) {\n try {\n const data = JSON.parse(readFileSync(FEEDBACK_FILE, 'utf-8'));\n this.localFeedback = data.feedback || [];\n } catch {\n // Ignore parse errors\n }\n }\n }\n\n private saveLocalData(): void {\n ensureStorageDir();\n\n // Save patterns\n writeFileSync(\n PATTERNS_FILE,\n JSON.stringify({ patterns: Array.from(this.localPatterns.values()) }, null, 2)\n );\n\n // Save reports (keep last 100)\n const recentReports = this.localReports.slice(-100);\n writeFileSync(REPORTS_FILE, JSON.stringify({ reports: recentReports }, null, 2));\n\n // Save feedback (keep last 500)\n const recentFeedback = this.localFeedback.slice(-500);\n writeFileSync(FEEDBACK_FILE, JSON.stringify({ feedback: recentFeedback }, null, 2));\n }\n\n // ==========================================================================\n // Collection Methods\n // ==========================================================================\n\n /**\n * Record an analysis run\n */\n async recordAnalysis(\n projectPath: string,\n frameworks: string[],\n languages: string[],\n results: {\n total: number;\n verified: number;\n drift: number;\n undocumented: number;\n unimplemented: number;\n driftItems: Array<{\n id: string;\n description: string;\n category?: string;\n severity?: string;\n sourceFile?: string;\n accepted?: boolean;\n }>;\n analysisTimeMs?: number;\n tokensUsed?: number;\n debatesTriggered?: number;\n debatesOverturned?: number;\n overallConfidence?: number;\n },\n docsCount: number,\n codeCount: number\n ): Promise<void> {\n if (!this.config.enabled || !this.config.collectReports) {\n return;\n }\n\n // Create anonymized report\n const report = anonymizeAnalysisReport(\n projectPath,\n frameworks,\n languages,\n results,\n docsCount,\n codeCount\n );\n\n // Validate no PII\n const validation = validateAnonymizedReport(report);\n if (!validation.valid) {\n console.warn('Anonymized report validation failed:', validation.issues);\n return;\n }\n\n // Store locally\n this.localReports.push(report);\n\n // Extract and store patterns from drift items\n for (const drift of results.driftItems) {\n await this.recordDriftPattern(\n drift.description,\n (drift.category || 'other') as DriftCategory,\n (drift.severity || 'medium') as DriftSeverity,\n frameworks,\n languages\n );\n }\n\n // Save to disk\n this.saveLocalData();\n\n // Optionally sync to cloud\n if (this.config.cloudEndpoint) {\n await this.syncToCloud(report);\n }\n }\n\n /**\n * Record a drift pattern observation\n */\n async recordDriftPattern(\n description: string,\n category: DriftCategory,\n severity: DriftSeverity,\n frameworks: string[],\n languages: string[]\n ): Promise<void> {\n if (!this.config.enabled) return;\n\n const patternKey = extractDriftType(description);\n\n // Check if pattern already exists\n const existing = this.localPatterns.get(patternKey);\n\n if (existing) {\n // Update existing pattern\n existing.frequency++;\n existing.sampleSize++;\n existing.frameworks = [...new Set([...existing.frameworks, ...frameworks])];\n existing.languages = [...new Set([...existing.languages, ...languages])];\n existing.lastSeenAt = new Date();\n existing.updatedAt = new Date();\n } else {\n // Create new pattern\n const newPattern: DriftPattern = {\n id: `local_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,\n patternKey,\n description: this.generalizeDescription(description),\n category,\n severity,\n frameworks,\n languages,\n frequency: 1,\n falsePositiveRate: 0,\n acceptanceRate: 1,\n sampleSize: 1,\n createdAt: new Date(),\n updatedAt: new Date(),\n lastSeenAt: new Date(),\n };\n this.localPatterns.set(patternKey, newPattern);\n }\n }\n\n /**\n * Record user feedback (implicit or explicit)\n */\n async recordFeedback(\n projectPath: string,\n ourPrediction: VerificationStatus,\n actualStatus: VerificationStatus | undefined,\n source: FeedbackSource,\n context?: {\n framework?: string;\n language?: string;\n filePath?: string;\n driftType?: string;\n category?: string;\n patternKey?: string;\n },\n reason?: string\n ): Promise<void> {\n if (!this.config.enabled || !this.config.collectFeedback) {\n return;\n }\n\n const feedback: AccuracyFeedback = {\n id: `fb_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,\n projectHash: hashProject(projectPath),\n patternId: context?.patternKey\n ? this.localPatterns.get(context.patternKey)?.id\n : undefined,\n ourPrediction,\n actualStatus,\n context: anonymizeFeedbackContext(\n context?.framework,\n context?.language,\n context?.filePath,\n context?.driftType,\n context?.category\n ),\n feedbackSource: source,\n userReason: reason,\n createdAt: new Date(),\n };\n\n this.localFeedback.push(feedback);\n\n // Update pattern accuracy if we know the actual status\n if (actualStatus && context?.patternKey) {\n await this.updatePatternAccuracy(\n context.patternKey,\n ourPrediction === actualStatus\n );\n }\n\n this.saveLocalData();\n }\n\n /**\n * Update pattern accuracy based on feedback\n */\n private async updatePatternAccuracy(\n patternKey: string,\n wasCorrect: boolean\n ): Promise<void> {\n const pattern = this.localPatterns.get(patternKey);\n if (!pattern) return;\n\n // Use exponential moving average\n const alpha = 0.1; // Learning rate\n\n if (wasCorrect) {\n pattern.falsePositiveRate = pattern.falsePositiveRate * (1 - alpha);\n pattern.acceptanceRate = pattern.acceptanceRate * (1 - alpha) + alpha;\n } else {\n pattern.falsePositiveRate = pattern.falsePositiveRate * (1 - alpha) + alpha;\n pattern.acceptanceRate = pattern.acceptanceRate * (1 - alpha);\n }\n\n pattern.updatedAt = new Date();\n }\n\n // ==========================================================================\n // Query Methods\n // ==========================================================================\n\n /**\n * Get patterns relevant for a framework\n */\n getPatternsForFramework(framework: string, minFrequency = 1): DriftPattern[] {\n const patterns: DriftPattern[] = [];\n\n for (const pattern of this.localPatterns.values()) {\n if (pattern.frequency >= minFrequency) {\n if (\n pattern.frameworks.length === 0 ||\n pattern.frameworks.includes(framework.toLowerCase())\n ) {\n patterns.push(pattern);\n }\n }\n }\n\n return patterns.sort((a, b) => b.frequency - a.frequency);\n }\n\n /**\n * Get all local patterns\n */\n getAllPatterns(): DriftPattern[] {\n return Array.from(this.localPatterns.values()).sort(\n (a, b) => b.frequency - a.frequency\n );\n }\n\n /**\n * Get pattern by key\n */\n getPattern(patternKey: string): DriftPattern | undefined {\n return this.localPatterns.get(patternKey);\n }\n\n /**\n * Get local statistics\n */\n getLocalStats(): {\n totalPatterns: number;\n totalReports: number;\n totalFeedback: number;\n topPatterns: Array<{ key: string; frequency: number }>;\n } {\n const patterns = Array.from(this.localPatterns.values());\n const topPatterns = patterns\n .sort((a, b) => b.frequency - a.frequency)\n .slice(0, 10)\n .map((p) => ({ key: p.patternKey, frequency: p.frequency }));\n\n return {\n totalPatterns: patterns.length,\n totalReports: this.localReports.length,\n totalFeedback: this.localFeedback.length,\n topPatterns,\n };\n }\n\n // ==========================================================================\n // Cloud Sync\n // ==========================================================================\n\n /**\n * Sync a report to the cloud endpoint\n */\n private async syncToCloud(report: AnonymizedAnalysisReport): Promise<void> {\n if (!this.config.cloudEndpoint) return;\n\n try {\n const response = await fetch(`${this.config.cloudEndpoint}/api/knowledge-base/report`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(report),\n });\n\n if (!response.ok) {\n console.warn('Failed to sync report to cloud:', response.status);\n }\n } catch (err) {\n // Silently fail - cloud sync is optional\n console.debug('Cloud sync failed:', err);\n }\n }\n\n /**\n * Pull latest patterns from cloud\n */\n async pullFromCloud(): Promise<void> {\n if (!this.config.cloudEndpoint) return;\n\n try {\n const response = await fetch(`${this.config.cloudEndpoint}/api/knowledge-base/patterns`);\n\n if (!response.ok) {\n console.warn('Failed to pull patterns from cloud:', response.status);\n return;\n }\n\n const data = await response.json();\n const cloudPatterns = data.patterns || [];\n\n // Merge cloud patterns with local\n for (const cloudPattern of cloudPatterns) {\n const local = this.localPatterns.get(cloudPattern.patternKey);\n\n if (!local) {\n // Add new cloud pattern\n this.localPatterns.set(cloudPattern.patternKey, cloudPattern);\n } else if (cloudPattern.sampleSize > local.sampleSize) {\n // Cloud has more data, merge\n this.localPatterns.set(cloudPattern.patternKey, {\n ...cloudPattern,\n // Keep local-specific data\n id: local.id,\n createdAt: local.createdAt,\n });\n }\n }\n\n this.saveLocalData();\n } catch (err) {\n console.debug('Failed to pull from cloud:', err);\n }\n }\n\n // ==========================================================================\n // Helpers\n // ==========================================================================\n\n /**\n * Generalize a drift description to remove specifics\n */\n private generalizeDescription(description: string): string {\n // Remove specific numbers\n let generalized = description.replace(/\\b\\d+\\b/g, 'N');\n\n // Remove specific file paths\n generalized = generalized.replace(/\\/[a-zA-Z0-9_\\-./]+\\.(ts|js|py|go|java)/g, '[FILE]');\n\n // Remove specific function/variable names (common patterns)\n generalized = generalized.replace(/`[a-zA-Z_][a-zA-Z0-9_]*`/g, '`[NAME]`');\n\n // Truncate if too long\n if (generalized.length > 200) {\n generalized = generalized.substring(0, 197) + '...';\n }\n\n return generalized;\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet collectorInstance: PatternCollector | null = null;\n\nexport function getPatternCollector(config?: Partial<CollectorConfig>): PatternCollector {\n if (!collectorInstance) {\n collectorInstance = new PatternCollector(config);\n }\n return collectorInstance;\n}\n\nexport function resetPatternCollector(): void {\n collectorInstance = null;\n}\n","/**\n * Pattern Matcher\n *\n * Uses the knowledge base to enhance verification by:\n * - Pre-screening for likely drift based on known patterns\n * - Adjusting confidence based on historical accuracy\n * - Providing contextual hints to the AI\n */\n\nimport {\n DriftPattern,\n FrameworkRule,\n PatternMatch,\n FrameworkContext,\n DriftCategory,\n DriftSeverity,\n} from './types.js';\nimport { getPatternCollector, PatternCollector } from './collector.js';\nimport { extractDriftType } from './anonymizer.js';\n\n// ============================================================================\n// Built-in Pattern Database\n// ============================================================================\n\n/**\n * Hardcoded patterns that are universally applicable\n * These supplement learned patterns from the knowledge base\n */\nconst BUILT_IN_PATTERNS: Partial<DriftPattern>[] = [\n {\n patternKey: 'rate_limit_mismatch',\n description: 'Rate limiting values differ between documentation and implementation',\n category: 'api',\n severity: 'critical',\n detectionHint: 'Look for rate-limit middleware, compare numeric values with docs',\n autoFixSuggestion: 'Update documentation to match implemented rate limits, or adjust code',\n },\n {\n patternKey: 'auth_drift',\n description: 'Authentication flow or token handling differs from documented spec',\n category: 'security',\n severity: 'high',\n detectionHint: 'Check JWT expiry, refresh token flow, and session handling',\n autoFixSuggestion: 'Align authentication implementation with security documentation',\n },\n {\n patternKey: 'api_schema_mismatch',\n description: 'API request/response schemas differ from OpenAPI or type definitions',\n category: 'api',\n severity: 'high',\n detectionHint: 'Compare Zod/Joi schemas with OpenAPI definitions',\n autoFixSuggestion: 'Regenerate OpenAPI from code or update validation schemas',\n },\n {\n patternKey: 'env_vars_missing',\n description: 'Environment variables used in code are not documented',\n category: 'infrastructure',\n severity: 'medium',\n detectionHint: 'Search for process.env, os.environ references',\n autoFixSuggestion: 'Create .env.example and document all required variables',\n },\n {\n patternKey: 'pricing_drift',\n description: 'Pricing, quotas, or tier limits differ between docs and code',\n category: 'data',\n severity: 'critical',\n detectionHint: 'Check subscription/billing code against pricing documentation',\n autoFixSuggestion: 'Synchronize pricing documentation with implementation',\n },\n {\n patternKey: 'error_codes_drift',\n description: 'Error codes or status codes differ from documentation',\n category: 'api',\n severity: 'medium',\n detectionHint: 'Map all thrown errors to documented error codes',\n autoFixSuggestion: 'Document all error codes or update error handling',\n },\n {\n patternKey: 'database_drift',\n description: 'Database schema differs from data model documentation',\n category: 'data',\n severity: 'high',\n detectionHint: 'Compare Prisma/Drizzle schema with docs',\n autoFixSuggestion: 'Run schema diff and update documentation',\n },\n {\n patternKey: 'webhook_missing',\n description: 'Webhook event types not documented',\n category: 'integration',\n severity: 'high',\n detectionHint: 'Search for webhook handlers and event types',\n autoFixSuggestion: 'Document all webhook event types and payloads',\n },\n];\n\n// ============================================================================\n// Pattern Matcher Class\n// ============================================================================\n\nexport class PatternMatcher {\n private collector: PatternCollector;\n private cachedContext: Map<string, FrameworkContext> = new Map();\n\n constructor() {\n this.collector = getPatternCollector();\n }\n\n // ==========================================================================\n // Context Building\n // ==========================================================================\n\n /**\n * Build framework context for verification\n */\n buildFrameworkContext(frameworks: string[], languages: string[]): FrameworkContext {\n const cacheKey = [...frameworks, ...languages].sort().join(':');\n\n // Check cache\n const cached = this.cachedContext.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // Collect relevant patterns\n const patterns: DriftPattern[] = [];\n\n // Add built-in patterns\n for (const builtIn of BUILT_IN_PATTERNS) {\n patterns.push({\n id: `builtin_${builtIn.patternKey}`,\n patternKey: builtIn.patternKey!,\n description: builtIn.description!,\n category: builtIn.category!,\n severity: builtIn.severity!,\n frameworks: [],\n languages: [],\n frequency: 9999, // High priority\n falsePositiveRate: 0.05,\n acceptanceRate: 0.95,\n sampleSize: 9999,\n detectionHint: builtIn.detectionHint,\n autoFixSuggestion: builtIn.autoFixSuggestion,\n createdAt: new Date(),\n updatedAt: new Date(),\n lastSeenAt: new Date(),\n });\n }\n\n // Add learned patterns for each framework\n for (const framework of frameworks) {\n const frameworkPatterns = this.collector.getPatternsForFramework(framework);\n for (const pattern of frameworkPatterns) {\n // Avoid duplicates\n if (!patterns.find((p) => p.patternKey === pattern.patternKey)) {\n patterns.push(pattern);\n }\n }\n }\n\n // Sort by relevance (frequency * (1 - false positive rate))\n patterns.sort((a, b) => {\n const scoreA = a.frequency * (1 - a.falsePositiveRate);\n const scoreB = b.frequency * (1 - b.falsePositiveRate);\n return scoreB - scoreA;\n });\n\n const context: FrameworkContext = {\n frameworks,\n languages,\n patterns: patterns.slice(0, 50), // Top 50 patterns\n rules: [], // TODO: Load framework rules from DB\n };\n\n // Cache for 5 minutes\n this.cachedContext.set(cacheKey, context);\n setTimeout(() => this.cachedContext.delete(cacheKey), 5 * 60 * 1000);\n\n return context;\n }\n\n // ==========================================================================\n // Pattern Matching\n // ==========================================================================\n\n /**\n * Find patterns that match a drift description\n */\n matchDrift(\n description: string,\n context: FrameworkContext\n ): PatternMatch[] {\n const matches: PatternMatch[] = [];\n const driftType = extractDriftType(description);\n const descLower = description.toLowerCase();\n\n for (const pattern of context.patterns) {\n let matchScore = 0;\n const reasons: string[] = [];\n\n // Exact type match\n if (pattern.patternKey === driftType) {\n matchScore += 50;\n reasons.push('Drift type matches known pattern');\n }\n\n // Keyword matching\n const keywords = this.extractKeywords(pattern.description);\n for (const keyword of keywords) {\n if (descLower.includes(keyword.toLowerCase())) {\n matchScore += 10;\n reasons.push(`Contains keyword: ${keyword}`);\n }\n }\n\n // Category match\n if (descLower.includes(pattern.category)) {\n matchScore += 5;\n reasons.push(`Category match: ${pattern.category}`);\n }\n\n // Only include significant matches\n if (matchScore >= 30) {\n matches.push({\n pattern,\n matchScore,\n reasons,\n });\n }\n }\n\n // Sort by score\n return matches.sort((a, b) => b.matchScore - a.matchScore);\n }\n\n /**\n * Adjust confidence based on known pattern accuracy\n */\n adjustConfidence(\n baseConfidence: number,\n patternMatch?: PatternMatch\n ): number {\n if (!patternMatch) {\n return baseConfidence;\n }\n\n const pattern = patternMatch.pattern;\n\n // If pattern has high false positive rate, reduce confidence\n if (pattern.falsePositiveRate > 0.3) {\n return Math.round(baseConfidence * (1 - pattern.falsePositiveRate * 0.5));\n }\n\n // If pattern is frequently accepted, boost confidence slightly\n if (pattern.acceptanceRate > 0.9 && pattern.sampleSize > 10) {\n return Math.min(100, Math.round(baseConfidence * 1.1));\n }\n\n return baseConfidence;\n }\n\n // ==========================================================================\n // Pre-screening\n // ==========================================================================\n\n /**\n * Pre-screen code/docs for likely drift areas\n */\n prescreenForDrift(\n docsContent: string,\n codeContent: string,\n context: FrameworkContext\n ): string[] {\n const hints: string[] = [];\n const docsLower = docsContent.toLowerCase();\n const codeLower = codeContent.toLowerCase();\n\n for (const pattern of context.patterns.slice(0, 20)) {\n const hint = this.checkForPatternIndicators(\n pattern,\n docsLower,\n codeLower\n );\n if (hint) {\n hints.push(hint);\n }\n }\n\n return hints;\n }\n\n /**\n * Check if a pattern's indicators are present\n */\n private checkForPatternIndicators(\n pattern: DriftPattern,\n docsContent: string,\n codeContent: string\n ): string | null {\n const indicators: Record<string, { docs: string[]; code: string[] }> = {\n rate_limit_mismatch: {\n docs: ['rate limit', 'requests per', 'throttl'],\n code: ['rateLimit', 'rateLimiter', 'throttle', 'requests:', 'limit:'],\n },\n auth_drift: {\n docs: ['authentication', 'jwt', 'token expir', 'session'],\n code: ['jwt', 'token', 'auth', 'session', 'expir'],\n },\n api_schema_mismatch: {\n docs: ['schema', 'request body', 'response', 'parameters'],\n code: ['.parse(', 'zod', 'joi', 'yup', 'validation'],\n },\n pricing_drift: {\n docs: ['pricing', 'tier', 'plan', 'subscription', 'quota'],\n code: ['price', 'tier', 'plan', 'quota', 'limit'],\n },\n env_vars_missing: {\n docs: ['environment', '.env', 'configuration'],\n code: ['process.env', 'os.environ', 'dotenv'],\n },\n };\n\n const patternIndicators = indicators[pattern.patternKey];\n if (!patternIndicators) return null;\n\n const docsHasIndicator = patternIndicators.docs.some((i) =>\n docsContent.includes(i.toLowerCase())\n );\n const codeHasIndicator = patternIndicators.code.some((i) =>\n codeContent.includes(i.toLowerCase())\n );\n\n // If both docs and code have indicators, this area is worth checking\n if (docsHasIndicator && codeHasIndicator) {\n return `Check for ${pattern.patternKey}: ${pattern.detectionHint || pattern.description}`;\n }\n\n // If only code has indicator, might be undocumented\n if (codeHasIndicator && !docsHasIndicator) {\n return `Potential undocumented: Code has ${pattern.patternKey} patterns but docs don't mention it`;\n }\n\n return null;\n }\n\n // ==========================================================================\n // AI Prompt Enhancement\n // ==========================================================================\n\n /**\n * Generate additional context for AI prompts based on patterns\n */\n generatePromptEnhancements(context: FrameworkContext): string {\n const lines: string[] = [\n '## Known Drift Patterns to Check',\n '',\n 'Based on historical data, pay special attention to these common drift areas:',\n '',\n ];\n\n // Add top patterns with detection hints\n const topPatterns = context.patterns.slice(0, 10);\n for (const pattern of topPatterns) {\n lines.push(`### ${pattern.patternKey}`);\n lines.push(`- **Severity:** ${pattern.severity}`);\n lines.push(`- **Category:** ${pattern.category}`);\n if (pattern.detectionHint) {\n lines.push(`- **Detection hint:** ${pattern.detectionHint}`);\n }\n if (pattern.falsePositiveRate > 0.2) {\n lines.push(`- **Note:** This pattern has ${Math.round(pattern.falsePositiveRate * 100)}% false positive rate, verify carefully`);\n }\n lines.push('');\n }\n\n // Add framework-specific rules\n if (context.rules.length > 0) {\n lines.push('## Framework-Specific Rules');\n lines.push('');\n for (const rule of context.rules) {\n lines.push(`- **${rule.framework}:** ${JSON.stringify(rule.ruleData)}`);\n }\n }\n\n return lines.join('\\n');\n }\n\n // ==========================================================================\n // Helpers\n // ==========================================================================\n\n private extractKeywords(text: string): string[] {\n // Remove common words and extract meaningful terms\n const stopWords = new Set([\n 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will',\n 'would', 'could', 'should', 'may', 'might', 'must', 'shall',\n 'can', 'need', 'dare', 'ought', 'used', 'to', 'of', 'in',\n 'for', 'on', 'with', 'at', 'by', 'from', 'as', 'into',\n 'through', 'during', 'before', 'after', 'above', 'below',\n 'between', 'under', 'again', 'further', 'then', 'once',\n 'and', 'but', 'or', 'nor', 'not', 'only', 'own', 'same',\n 'than', 'too', 'very', 'just',\n ]);\n\n const words = text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((word) => word.length > 2 && !stopWords.has(word));\n\n return [...new Set(words)];\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.cachedContext.clear();\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet matcherInstance: PatternMatcher | null = null;\n\nexport function getPatternMatcher(): PatternMatcher {\n if (!matcherInstance) {\n matcherInstance = new PatternMatcher();\n }\n return matcherInstance;\n}\n","/**\n * Knowledge Base Module\n *\n * Provides network effects through anonymized pattern learning:\n * - Collect drift patterns from all analyses (privacy-safe)\n * - Match new findings against known patterns\n * - Improve accuracy over time through federated learning\n */\n\n// Types\nexport {\n DriftPattern,\n DriftCategory,\n DriftSeverity,\n FrameworkRule,\n AccuracyFeedback,\n FeedbackType,\n AnonymizedAnalysisReport,\n PatternMatch,\n FrameworkContext,\n CollectorConfig,\n} from './types.js';\n\n// Anonymizer - PII removal and hashing\nexport {\n hashProject,\n hashAnalysis,\n hashFilePattern,\n containsPII,\n sanitize,\n anonymizeAnalysisReport,\n validateAnonymizedReport,\n extractDriftType,\n} from './anonymizer.js';\n\n// Pattern Collector - Local storage and cloud sync\nexport {\n PatternCollector,\n getPatternCollector,\n} from './collector.js';\n\n// Pattern Matcher - Match drifts to known patterns\nexport {\n PatternMatcher,\n getPatternMatcher,\n} from './matcher.js';\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\nimport { getPatternCollector, PatternCollector } from './collector.js';\nimport { getPatternMatcher, PatternMatcher } from './matcher.js';\nimport { anonymizeAnalysisReport, validateAnonymizedReport } from './anonymizer.js';\nimport { AnonymizedAnalysisReport, FrameworkContext } from './types.js';\n\n/**\n * Initialize the knowledge base system\n * Call this at startup to load cached patterns\n */\nexport async function initializeKnowledgeBase(): Promise<{\n collector: PatternCollector;\n matcher: PatternMatcher;\n}> {\n const collector = getPatternCollector();\n const matcher = getPatternMatcher();\n\n // Load patterns from cache\n await collector.loadFromCache();\n\n return { collector, matcher };\n}\n\n/**\n * Record an analysis and learn from it\n */\nexport async function recordAnalysis(\n report: AnonymizedAnalysisReport,\n options?: { syncToCloud?: boolean }\n): Promise<void> {\n // Validate the report is properly anonymized\n const validation = validateAnonymizedReport(report);\n if (!validation.valid) {\n console.warn(`Report validation failed: ${validation.reasons.join(', ')}`);\n return;\n }\n\n const collector = getPatternCollector();\n await collector.recordAnalysis(report);\n\n // Clear matcher cache to pick up new patterns\n const matcher = getPatternMatcher();\n matcher.clearCache();\n}\n\n/**\n * Get framework-specific context for verification\n */\nexport function getFrameworkContext(\n frameworks: string[],\n languages: string[]\n): FrameworkContext {\n const matcher = getPatternMatcher();\n return matcher.buildFrameworkContext(frameworks, languages);\n}\n\n/**\n * Pre-screen content for likely drift areas\n */\nexport function prescreenForDrift(\n docsContent: string,\n codeContent: string,\n context: FrameworkContext\n): string[] {\n const matcher = getPatternMatcher();\n return matcher.prescreenForDrift(docsContent, codeContent, context);\n}\n\n/**\n * Get AI prompt enhancements based on known patterns\n */\nexport function getPromptEnhancements(context: FrameworkContext): string {\n const matcher = getPatternMatcher();\n return matcher.generatePromptEnhancements(context);\n}\n","/**\n * Rules Registry\n *\n * Manages local and marketplace rules for verification.\n * Provides rule installation, discovery, and execution.\n */\n\nimport { createHash } from 'crypto';\nimport {\n VerificationRule,\n RuleCollection,\n RuleResult,\n RuleResultDetails,\n RuleTarget,\n PatternType,\n RuleSeverity,\n LocalRuleStorage,\n RuleConfig,\n MarketplaceSearchParams,\n MarketplaceSearchResult,\n} from './types.js';\n\n// ============================================================================\n// Built-in Rules\n// ============================================================================\n\nconst BUILTIN_RULES: VerificationRule[] = [\n {\n id: 'auth-jwt-expiry',\n name: 'JWT Token Expiry',\n description: 'Verifies that JWT token expiry is documented and implemented consistently',\n version: '1.0.0',\n target: {\n frameworks: ['nextjs', 'express', 'fastify'],\n categories: ['authentication', 'security'],\n },\n pattern: {\n type: 'consistency',\n definition: {\n consistencyRules: [\n {\n docField: 'jwt.expiry',\n codeField: 'expiresIn',\n comparison: 'similar',\n tolerance: 0.2,\n },\n ],\n },\n severity: 'error',\n messageTemplate: 'JWT expiry mismatch: docs say {{docValue}}, code uses {{codeValue}}',\n },\n author: { id: 'vaspera', name: 'VasperaPM', verified: true },\n stats: { downloads: 1000, uses: 5000, successRate: 95, falsePositiveRate: 2, communityRating: 4.8, reviews: 50 },\n tags: ['authentication', 'jwt', 'security'],\n createdAt: '2024-01-01T00:00:00Z',\n updatedAt: '2024-06-01T00:00:00Z',\n publishedAt: '2024-01-15T00:00:00Z',\n },\n {\n id: 'rate-limit-documented',\n name: 'Rate Limiting Documentation',\n description: 'Ensures rate limits in code are documented',\n version: '1.0.0',\n target: {\n frameworks: ['nextjs', 'express', 'fastify'],\n categories: ['api', 'security', 'performance'],\n },\n pattern: {\n type: 'doc_exists',\n definition: {\n codePattern: 'rateLimit|rateLimiter|RATE_LIMIT|requestsPerMinute|maxRequests',\n docPattern: 'rate.?limit|requests?.?per|throttl',\n },\n severity: 'warning',\n messageTemplate: 'Rate limiting is implemented but not documented',\n },\n author: { id: 'vaspera', name: 'VasperaPM', verified: true },\n stats: { downloads: 800, uses: 3000, successRate: 90, falsePositiveRate: 5, communityRating: 4.5, reviews: 30 },\n tags: ['rate-limiting', 'api', 'documentation'],\n createdAt: '2024-01-01T00:00:00Z',\n updatedAt: '2024-05-01T00:00:00Z',\n publishedAt: '2024-01-15T00:00:00Z',\n },\n {\n id: 'api-endpoint-documented',\n name: 'API Endpoint Documentation',\n description: 'Ensures all API endpoints have documentation',\n version: '1.0.0',\n target: {\n frameworks: ['nextjs', 'express', 'fastify', 'hono'],\n categories: ['api', 'documentation'],\n filePatterns: ['**/api/**', '**/routes/**', '**/handlers/**'],\n },\n pattern: {\n type: 'doc_exists',\n definition: {\n codePattern: '(app|router)\\\\.(get|post|put|delete|patch)',\n docPattern: '(GET|POST|PUT|DELETE|PATCH)\\\\s+\\\\/',\n },\n severity: 'warning',\n messageTemplate: 'API endpoint {{endpoint}} is not documented',\n },\n author: { id: 'vaspera', name: 'VasperaPM', verified: true },\n stats: { downloads: 1200, uses: 6000, successRate: 92, falsePositiveRate: 3, communityRating: 4.7, reviews: 60 },\n tags: ['api', 'documentation', 'endpoints'],\n createdAt: '2024-01-01T00:00:00Z',\n updatedAt: '2024-06-01T00:00:00Z',\n publishedAt: '2024-01-15T00:00:00Z',\n },\n {\n id: 'error-handling-consistent',\n name: 'Error Handling Consistency',\n description: 'Verifies error response formats are consistent with documentation',\n version: '1.0.0',\n target: {\n categories: ['error_handling', 'api'],\n },\n pattern: {\n type: 'consistency',\n definition: {\n consistencyRules: [\n {\n docField: 'error.format',\n codeField: 'errorResponse',\n comparison: 'similar',\n tolerance: 0.3,\n },\n ],\n },\n severity: 'error',\n messageTemplate: 'Error response format does not match documentation',\n },\n author: { id: 'vaspera', name: 'VasperaPM', verified: true },\n stats: { downloads: 600, uses: 2000, successRate: 88, falsePositiveRate: 8, communityRating: 4.3, reviews: 25 },\n tags: ['error-handling', 'api', 'consistency'],\n createdAt: '2024-02-01T00:00:00Z',\n updatedAt: '2024-05-01T00:00:00Z',\n publishedAt: '2024-02-15T00:00:00Z',\n },\n {\n id: 'env-vars-documented',\n name: 'Environment Variables Documentation',\n description: 'Ensures all environment variables used in code are documented',\n version: '1.0.0',\n target: {\n categories: ['documentation', 'security'],\n },\n pattern: {\n type: 'doc_exists',\n definition: {\n codePattern: 'process\\\\.env\\\\.(\\\\w+)|env\\\\.(\\\\w+)',\n docPattern: 'environment|env|config',\n },\n severity: 'warning',\n messageTemplate: 'Environment variable {{envVar}} is not documented',\n },\n author: { id: 'vaspera', name: 'VasperaPM', verified: true },\n stats: { downloads: 900, uses: 4000, successRate: 85, falsePositiveRate: 10, communityRating: 4.2, reviews: 35 },\n tags: ['environment', 'configuration', 'documentation'],\n createdAt: '2024-01-01T00:00:00Z',\n updatedAt: '2024-04-01T00:00:00Z',\n publishedAt: '2024-01-15T00:00:00Z',\n },\n];\n\n// ============================================================================\n// Rules Registry Class\n// ============================================================================\n\nexport class RulesRegistry {\n private storage: LocalRuleStorage;\n private builtinRules: Map<string, VerificationRule>;\n\n constructor() {\n this.builtinRules = new Map(BUILTIN_RULES.map((r) => [r.id, r]));\n this.storage = {\n installedRules: new Map(),\n customRules: new Map(),\n enabledRules: new Set(BUILTIN_RULES.map((r) => r.id)),\n ruleConfig: new Map(),\n };\n }\n\n // ==========================================================================\n // Rule Access\n // ==========================================================================\n\n /**\n * Get all available rules (builtin + installed + custom)\n */\n getAllRules(): VerificationRule[] {\n return [\n ...this.builtinRules.values(),\n ...this.storage.installedRules.values(),\n ...this.storage.customRules.values(),\n ];\n }\n\n /**\n * Get enabled rules only\n */\n getEnabledRules(): VerificationRule[] {\n return this.getAllRules().filter((r) => this.storage.enabledRules.has(r.id));\n }\n\n /**\n * Get rules matching target criteria\n */\n getRulesForTarget(target: Partial<RuleTarget>): VerificationRule[] {\n return this.getEnabledRules().filter((rule) => {\n // Check framework match\n if (target.frameworks && rule.target.frameworks) {\n const hasMatch = target.frameworks.some((f) =>\n rule.target.frameworks!.includes(f)\n );\n if (!hasMatch && rule.target.frameworks.length > 0) return false;\n }\n\n // Check language match\n if (target.languages && rule.target.languages) {\n const hasMatch = target.languages.some((l) =>\n rule.target.languages!.includes(l)\n );\n if (!hasMatch && rule.target.languages.length > 0) return false;\n }\n\n // Check category match\n if (target.categories && rule.target.categories) {\n const hasMatch = target.categories.some((c) =>\n rule.target.categories!.includes(c)\n );\n if (!hasMatch && rule.target.categories.length > 0) return false;\n }\n\n return true;\n });\n }\n\n /**\n * Get a specific rule by ID\n */\n getRule(id: string): VerificationRule | undefined {\n return (\n this.builtinRules.get(id) ||\n this.storage.installedRules.get(id) ||\n this.storage.customRules.get(id)\n );\n }\n\n // ==========================================================================\n // Rule Management\n // ==========================================================================\n\n /**\n * Enable a rule\n */\n enableRule(id: string): boolean {\n const rule = this.getRule(id);\n if (!rule) return false;\n this.storage.enabledRules.add(id);\n return true;\n }\n\n /**\n * Disable a rule\n */\n disableRule(id: string): boolean {\n return this.storage.enabledRules.delete(id);\n }\n\n /**\n * Configure a rule\n */\n configureRule(id: string, config: Partial<RuleConfig>): boolean {\n const rule = this.getRule(id);\n if (!rule) return false;\n\n const existing = this.storage.ruleConfig.get(id) || { enabled: true };\n this.storage.ruleConfig.set(id, { ...existing, ...config });\n return true;\n }\n\n /**\n * Install a rule from marketplace\n */\n installRule(rule: VerificationRule): void {\n this.storage.installedRules.set(rule.id, rule);\n this.storage.enabledRules.add(rule.id);\n }\n\n /**\n * Uninstall a rule\n */\n uninstallRule(id: string): boolean {\n this.storage.enabledRules.delete(id);\n return this.storage.installedRules.delete(id);\n }\n\n /**\n * Add a custom rule\n */\n addCustomRule(rule: Omit<VerificationRule, 'id' | 'stats' | 'createdAt' | 'updatedAt'>): VerificationRule {\n const id = `custom-${createHash('md5').update(rule.name + Date.now()).digest('hex').substring(0, 8)}`;\n const now = new Date().toISOString();\n\n const fullRule: VerificationRule = {\n ...rule,\n id,\n stats: {\n downloads: 0,\n uses: 0,\n successRate: 0,\n falsePositiveRate: 0,\n communityRating: 0,\n reviews: 0,\n },\n createdAt: now,\n updatedAt: now,\n };\n\n this.storage.customRules.set(id, fullRule);\n this.storage.enabledRules.add(id);\n\n return fullRule;\n }\n\n /**\n * Remove a custom rule\n */\n removeCustomRule(id: string): boolean {\n this.storage.enabledRules.delete(id);\n return this.storage.customRules.delete(id);\n }\n\n // ==========================================================================\n // Rule Execution\n // ==========================================================================\n\n /**\n * Execute a single rule against content\n */\n executeRule(\n rule: VerificationRule,\n docs: string,\n code: string\n ): RuleResult {\n const config = this.storage.ruleConfig.get(rule.id);\n const severity = config?.severity || rule.pattern.severity;\n\n try {\n const result = this.evaluatePattern(rule, docs, code);\n\n return {\n ruleId: rule.id,\n ruleName: rule.name,\n passed: result.passed,\n severity,\n message: result.message || (result.passed ? 'Rule passed' : rule.description),\n details: result.details,\n };\n } catch (error) {\n return {\n ruleId: rule.id,\n ruleName: rule.name,\n passed: false,\n severity: 'error',\n message: `Rule execution error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n };\n }\n }\n\n /**\n * Execute all applicable rules\n */\n executeAllRules(\n docs: string,\n code: string,\n target?: Partial<RuleTarget>\n ): RuleResult[] {\n const rules = target ? this.getRulesForTarget(target) : this.getEnabledRules();\n\n return rules.map((rule) => this.executeRule(rule, docs, code));\n }\n\n // ==========================================================================\n // Pattern Evaluation\n // ==========================================================================\n\n private evaluatePattern(\n rule: VerificationRule,\n docs: string,\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n const { type, definition } = rule.pattern;\n\n switch (type) {\n case 'code_exists':\n return this.evaluateCodeExists(definition, code);\n\n case 'code_absent':\n return this.evaluateCodeAbsent(definition, code);\n\n case 'doc_exists':\n return this.evaluateDocExists(definition, docs, code);\n\n case 'doc_matches':\n return this.evaluateDocMatches(definition, docs);\n\n case 'consistency':\n return this.evaluateConsistency(definition, docs, code);\n\n case 'naming':\n return this.evaluateNaming(definition, code);\n\n case 'structure':\n return this.evaluateStructure(definition, code);\n\n default:\n return { passed: true, message: 'Unknown pattern type, skipping' };\n }\n }\n\n private evaluateCodeExists(\n definition: VerificationRule['pattern']['definition'],\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.codePattern) {\n return { passed: true, message: 'No code pattern defined' };\n }\n\n const regex = new RegExp(definition.codePattern, 'gi');\n const matches = code.match(regex);\n\n if (matches && matches.length > 0) {\n return {\n passed: true,\n message: `Found ${matches.length} matches`,\n details: { evidence: matches.slice(0, 5) },\n };\n }\n\n return {\n passed: false,\n message: 'Required code pattern not found',\n };\n }\n\n private evaluateCodeAbsent(\n definition: VerificationRule['pattern']['definition'],\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.codePattern) {\n return { passed: true, message: 'No code pattern defined' };\n }\n\n const regex = new RegExp(definition.codePattern, 'gi');\n const matches = code.match(regex);\n\n if (!matches || matches.length === 0) {\n return { passed: true, message: 'Pattern correctly absent' };\n }\n\n return {\n passed: false,\n message: `Found ${matches.length} instances that should be absent`,\n details: { evidence: matches.slice(0, 5) },\n };\n }\n\n private evaluateDocExists(\n definition: VerificationRule['pattern']['definition'],\n docs: string,\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.codePattern || !definition.docPattern) {\n return { passed: true, message: 'Incomplete pattern definition' };\n }\n\n const codeRegex = new RegExp(definition.codePattern, 'gi');\n const docRegex = new RegExp(definition.docPattern, 'gi');\n\n const codeMatches = code.match(codeRegex);\n const docMatches = docs.match(docRegex);\n\n // If code has the pattern, docs should too\n if (codeMatches && codeMatches.length > 0) {\n if (docMatches && docMatches.length > 0) {\n return { passed: true, message: 'Pattern found in both code and docs' };\n }\n return {\n passed: false,\n message: 'Code pattern exists but not documented',\n details: {\n evidence: codeMatches.slice(0, 3),\n },\n };\n }\n\n return { passed: true, message: 'Pattern not in code, documentation check skipped' };\n }\n\n private evaluateDocMatches(\n definition: VerificationRule['pattern']['definition'],\n docs: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.docPattern) {\n return { passed: true, message: 'No doc pattern defined' };\n }\n\n const regex = new RegExp(definition.docPattern, 'gi');\n const matches = docs.match(regex);\n\n if (matches && matches.length > 0) {\n return { passed: true, message: `Found ${matches.length} matches in docs` };\n }\n\n return {\n passed: false,\n message: 'Required documentation pattern not found',\n };\n }\n\n private evaluateConsistency(\n definition: VerificationRule['pattern']['definition'],\n docs: string,\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.consistencyRules || definition.consistencyRules.length === 0) {\n return { passed: true, message: 'No consistency rules defined' };\n }\n\n const failures: string[] = [];\n\n for (const rule of definition.consistencyRules) {\n // Extract values from docs and code (simplified)\n const docValue = this.extractValue(docs, rule.docField);\n const codeValue = this.extractValue(code, rule.codeField);\n\n if (!docValue && !codeValue) continue;\n\n let isConsistent = false;\n\n switch (rule.comparison) {\n case 'exact':\n isConsistent = docValue === codeValue;\n break;\n case 'contains':\n isConsistent = docValue?.includes(codeValue || '') || codeValue?.includes(docValue || '');\n break;\n case 'similar':\n isConsistent = this.calculateSimilarity(docValue || '', codeValue || '') >= (1 - (rule.tolerance || 0.2));\n break;\n case 'exists':\n isConsistent = !!docValue && !!codeValue;\n break;\n }\n\n if (!isConsistent && (docValue || codeValue)) {\n failures.push(`${rule.docField} (${docValue || 'missing'}) vs ${rule.codeField} (${codeValue || 'missing'})`);\n }\n }\n\n if (failures.length === 0) {\n return { passed: true, message: 'Consistency check passed' };\n }\n\n return {\n passed: false,\n message: `Inconsistencies found: ${failures.join(', ')}`,\n details: { evidence: failures },\n };\n }\n\n private evaluateNaming(\n definition: VerificationRule['pattern']['definition'],\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.namingConvention) {\n return { passed: true, message: 'No naming convention defined' };\n }\n\n const { style, prefix, suffix, pattern } = definition.namingConvention;\n\n // Extract identifiers from code\n const identifiers = this.extractIdentifiers(code);\n const violations: string[] = [];\n\n for (const id of identifiers) {\n let valid = true;\n\n if (prefix && !id.startsWith(prefix)) valid = false;\n if (suffix && !id.endsWith(suffix)) valid = false;\n if (pattern && !new RegExp(pattern).test(id)) valid = false;\n\n if (!valid) {\n violations.push(id);\n }\n }\n\n if (violations.length === 0) {\n return { passed: true, message: 'Naming convention check passed' };\n }\n\n return {\n passed: false,\n message: `Naming violations found: ${violations.length}`,\n details: { evidence: violations.slice(0, 10) },\n };\n }\n\n private evaluateStructure(\n definition: VerificationRule['pattern']['definition'],\n code: string\n ): { passed: boolean; message?: string; details?: RuleResultDetails } {\n if (!definition.requiredElements || definition.requiredElements.length === 0) {\n return { passed: true, message: 'No required elements defined' };\n }\n\n const missing: string[] = [];\n\n for (const element of definition.requiredElements) {\n const regex = new RegExp(element, 'gi');\n if (!regex.test(code)) {\n missing.push(element);\n }\n }\n\n if (missing.length === 0) {\n return { passed: true, message: 'All required elements found' };\n }\n\n return {\n passed: false,\n message: `Missing required elements: ${missing.join(', ')}`,\n details: { evidence: missing },\n };\n }\n\n // ==========================================================================\n // Helper Methods\n // ==========================================================================\n\n private extractValue(text: string, field: string): string | null {\n // Try to find the field value in text\n const patterns = [\n new RegExp(`${field}[:\\\\s]+([\\\\w\\\\d\\\\-\\\\.]+)`, 'i'),\n new RegExp(`\"${field}\"[:\\\\s]+[\"']?([^\"'\\\\s,}]+)`, 'i'),\n new RegExp(`${field}\\\\s*=\\\\s*[\"']?([^\"'\\\\s;]+)`, 'i'),\n ];\n\n for (const pattern of patterns) {\n const match = text.match(pattern);\n if (match) return match[1];\n }\n\n return null;\n }\n\n private calculateSimilarity(a: string, b: string): number {\n if (!a || !b) return 0;\n const longer = a.length > b.length ? a : b;\n const shorter = a.length > b.length ? b : a;\n if (longer.length === 0) return 1.0;\n\n const editDistance = this.levenshteinDistance(longer, shorter);\n return (longer.length - editDistance) / longer.length;\n }\n\n private levenshteinDistance(a: string, b: string): number {\n const matrix: number[][] = [];\n\n for (let i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= a.length; j++) {\n matrix[0][j] = j;\n }\n\n for (let i = 1; i <= b.length; i++) {\n for (let j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j] + 1\n );\n }\n }\n }\n\n return matrix[b.length][a.length];\n }\n\n private extractIdentifiers(code: string): string[] {\n const identifiers: string[] = [];\n\n // Match function/variable/class names\n const patterns = [\n /(?:function|const|let|var|class)\\s+(\\w+)/g,\n /(\\w+)\\s*=/g,\n /export\\s+(?:function|const|class)\\s+(\\w+)/g,\n ];\n\n for (const pattern of patterns) {\n let match;\n while ((match = pattern.exec(code)) !== null) {\n if (match[1] && !identifiers.includes(match[1])) {\n identifiers.push(match[1]);\n }\n }\n }\n\n return identifiers;\n }\n\n // ==========================================================================\n // Statistics\n // ==========================================================================\n\n getStats(): {\n total: number;\n builtin: number;\n installed: number;\n custom: number;\n enabled: number;\n } {\n return {\n total: this.getAllRules().length,\n builtin: this.builtinRules.size,\n installed: this.storage.installedRules.size,\n custom: this.storage.customRules.size,\n enabled: this.storage.enabledRules.size,\n };\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet registryInstance: RulesRegistry | null = null;\n\nexport function getRulesRegistry(): RulesRegistry {\n if (!registryInstance) {\n registryInstance = new RulesRegistry();\n }\n return registryInstance;\n}\n\nexport function resetRulesRegistry(): void {\n registryInstance = null;\n}\n","/**\n * Community Rules Marketplace Module\n *\n * Provides shareable verification rules that enable network effects.\n * Rules can be discovered, installed, and contributed by the community.\n *\n * Key Features:\n * - Built-in rules for common patterns\n * - Custom rule creation\n * - Rule execution engine\n * - Community rule sharing (future)\n */\n\n// Types\nexport type {\n VerificationRule,\n RuleTarget,\n RulePattern,\n PatternType,\n PatternDefinition,\n ConsistencyRule,\n NamingConvention,\n RuleSeverity,\n RuleFix,\n RuleAuthor,\n RuleStats,\n RuleCollection,\n CollectionStats,\n RuleResult,\n RuleResultDetails,\n MarketplaceSearchParams,\n MarketplaceSearchResult,\n RuleInstallResult,\n LocalRuleStorage,\n RuleConfig,\n RuleContribution,\n RuleTest,\n ContributionResult,\n RequirementCategory,\n} from './types.js';\n\n// Registry\nexport {\n RulesRegistry,\n getRulesRegistry,\n resetRulesRegistry,\n} from './rules-registry.js';\n","/**\n * Git History Analysis Types\n *\n * Types for analyzing git history to detect documentation freshness,\n * code-doc desync, and drift risk patterns.\n */\n\n// ============================================================================\n// Commit & Change Types\n// ============================================================================\n\nexport interface CommitInfo {\n hash: string;\n message: string;\n date: Date;\n author: string;\n email?: string;\n}\n\nexport interface FileChange {\n file: string;\n additions: number;\n deletions: number;\n changeType: 'added' | 'modified' | 'deleted' | 'renamed';\n oldPath?: string; // For renamed files\n}\n\nexport interface CommitDetail extends CommitInfo {\n files: FileChange[];\n totalAdditions: number;\n totalDeletions: number;\n}\n\n// ============================================================================\n// Freshness Analysis Types\n// ============================================================================\n\nexport type ChangeFrequency = 'high' | 'medium' | 'low';\n\nexport interface FreshnessResult {\n /** File path */\n file: string;\n\n /** Last modification date */\n lastModified: Date;\n\n /** Days since last update */\n daysSinceUpdate: number;\n\n /** Author of last change */\n lastAuthor: string;\n\n /** Last commit message */\n lastCommitMessage: string;\n\n /** How often this file changes */\n changeFrequency: ChangeFrequency;\n\n /** Freshness score 0-100 (higher = fresher) */\n freshnessScore: number;\n\n /** Total number of commits for this file */\n totalCommits: number;\n}\n\nexport interface StaleDoc {\n file: string;\n daysSinceUpdate: number;\n lastAuthor: string;\n lastCommitMessage: string;\n relatedCodeFiles: string[];\n staleness: 'critical' | 'high' | 'medium';\n}\n\n// ============================================================================\n// Desync Detection Types\n// ============================================================================\n\nexport type DesyncRisk = 'high' | 'medium' | 'low';\n\nexport interface DesyncResult {\n /** Code file path */\n codePath: string;\n\n /** Documentation file path */\n docPath: string;\n\n /** Last code modification date */\n codeLastModified: Date;\n\n /** Last doc modification date */\n docLastModified: Date;\n\n /** Days between code and doc updates */\n daysBetween: number;\n\n /** Desync risk level */\n desyncRisk: DesyncRisk;\n\n /** Code changes since doc was last updated */\n codeChanges: CommitInfo[];\n\n /** Number of code commits since last doc update */\n commitsSinceDocUpdate: number;\n\n /** Recommendation for addressing desync */\n recommendation: string;\n}\n\nexport interface UndocumentedChange {\n /** File that changed */\n file: string;\n\n /** The commit info */\n commit: CommitInfo;\n\n /** Related documentation files that may need updates */\n relatedDocs: string[];\n\n /** Severity of the undocumented change */\n severity: 'high' | 'medium' | 'low';\n\n /** Reason why this change likely needs documentation */\n reason: string;\n}\n\n// ============================================================================\n// Drift Risk Types\n// ============================================================================\n\nexport interface DriftRiskFactors {\n /** How fresh the documentation is (0-100) */\n docFreshness: number;\n\n /** How frequently the code changes (0-100) */\n codeChangeFrequency: number;\n\n /** Historical drift rate for this file (0-100) */\n historicalDriftRate: number;\n\n /** File complexity score (0-100) */\n fileComplexity: number;\n}\n\nexport interface DriftRiskScore {\n /** File being analyzed */\n file: string;\n\n /** Overall risk score 0-100 (higher = more risk) */\n riskScore: number;\n\n /** Individual risk factors */\n factors: DriftRiskFactors;\n\n /** Risk level classification */\n riskLevel: 'critical' | 'high' | 'medium' | 'low';\n\n /** Recommendation for addressing drift risk */\n recommendation: string;\n}\n\nexport interface RiskArea {\n /** Files in this risk area */\n files: string[];\n\n /** Average risk score */\n averageRiskScore: number;\n\n /** Risk level */\n riskLevel: 'critical' | 'high' | 'medium' | 'low';\n\n /** Common patterns in this risk area */\n patterns: string[];\n\n /** Recommendation */\n recommendation: string;\n}\n\n// ============================================================================\n// Git Analysis Configuration\n// ============================================================================\n\nexport interface GitAnalysisConfig {\n /** Days threshold for considering docs stale (default: 90) */\n staleThresholdDays: number;\n\n /** Number of commits to analyze for change frequency */\n commitHistoryLimit: number;\n\n /** Weights for drift risk calculation */\n riskWeights: {\n docFreshness: number;\n codeChangeFrequency: number;\n historicalDriftRate: number;\n fileComplexity: number;\n };\n\n /** File patterns to consider as documentation */\n docPatterns: string[];\n\n /** File patterns to consider as code */\n codePatterns: string[];\n}\n\nexport const DEFAULT_GIT_ANALYSIS_CONFIG: GitAnalysisConfig = {\n staleThresholdDays: 90,\n commitHistoryLimit: 100,\n riskWeights: {\n docFreshness: 0.35,\n codeChangeFrequency: 0.25,\n historicalDriftRate: 0.25,\n fileComplexity: 0.15,\n },\n docPatterns: [\n '**/*.md',\n '**/*.mdx',\n '**/*.rst',\n '**/docs/**',\n '**/documentation/**',\n 'README*',\n 'CHANGELOG*',\n ],\n codePatterns: [\n '**/*.ts',\n '**/*.tsx',\n '**/*.js',\n '**/*.jsx',\n '**/*.py',\n '**/*.go',\n '**/*.rs',\n '**/*.java',\n ],\n};\n\n// ============================================================================\n// Analysis Results\n// ============================================================================\n\nexport interface GitAnalysisResult {\n /** Repository path */\n repoPath: string;\n\n /** Analysis timestamp */\n analyzedAt: Date;\n\n /** Freshness analysis */\n freshness: {\n staleDocuments: StaleDoc[];\n freshnessScores: Map<string, FreshnessResult>;\n averageFreshness: number;\n };\n\n /** Desync analysis */\n desync: {\n desyncPairs: DesyncResult[];\n undocumentedChanges: UndocumentedChange[];\n overallDesyncRisk: DesyncRisk;\n };\n\n /** Drift risk analysis */\n driftRisk: {\n fileScores: DriftRiskScore[];\n highRiskAreas: RiskArea[];\n overallRiskScore: number;\n };\n\n /** Summary statistics */\n summary: {\n totalDocsAnalyzed: number;\n totalCodeFilesAnalyzed: number;\n staleDocCount: number;\n desyncPairCount: number;\n highRiskFileCount: number;\n };\n}\n","/**\n * Git History Analyzer\n *\n * Core class for analyzing git history to extract commit information,\n * file change patterns, and temporal data for freshness/desync detection.\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport * as path from 'path';\nimport {\n DEFAULT_GIT_ANALYSIS_CONFIG,\n type CommitInfo,\n type CommitDetail,\n type FileChange,\n type ChangeFrequency,\n type GitAnalysisConfig,\n} from './types.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * GitHistoryAnalyzer provides low-level git operations for analyzing\n * repository history and file changes.\n */\nexport class GitHistoryAnalyzer {\n private repoPath: string;\n private config: GitAnalysisConfig;\n private isGitRepo: boolean | null = null;\n\n constructor(\n repoPath: string,\n config: Partial<GitAnalysisConfig> = {}\n ) {\n this.repoPath = path.resolve(repoPath);\n this.config = { ...DEFAULT_GIT_ANALYSIS_CONFIG, ...config };\n }\n\n // ==========================================================================\n // Git Validation\n // ==========================================================================\n\n /**\n * Check if the path is a valid git repository\n */\n async isValidGitRepo(): Promise<boolean> {\n if (this.isGitRepo !== null) {\n return this.isGitRepo;\n }\n\n try {\n await this.execGit('rev-parse --git-dir');\n this.isGitRepo = true;\n return true;\n } catch {\n this.isGitRepo = false;\n return false;\n }\n }\n\n // ==========================================================================\n // Commit History\n // ==========================================================================\n\n /**\n * Get the most recent commit for a file\n */\n async getLastCommit(filePath: string): Promise<CommitInfo | null> {\n const commits = await this.getFileCommits(filePath, 1);\n return commits[0] || null;\n }\n\n /**\n * Get commit history for a specific file\n */\n async getFileCommits(\n filePath: string,\n maxCount?: number\n ): Promise<CommitInfo[]> {\n const limit = maxCount || this.config.commitHistoryLimit;\n const relativePath = this.getRelativePath(filePath);\n\n try {\n // Use git log with a parseable format\n const format = '%H|%s|%ai|%an|%ae';\n const cmd = `log -n ${limit} --format=\"${format}\" -- \"${relativePath}\"`;\n const { stdout } = await this.execGit(cmd);\n\n if (!stdout.trim()) {\n return [];\n }\n\n return stdout\n .trim()\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => this.parseCommitLine(line));\n } catch {\n return [];\n }\n }\n\n /**\n * Get all commits in the repository\n */\n async getAllCommits(\n maxCount?: number,\n since?: Date\n ): Promise<CommitInfo[]> {\n const limit = maxCount || this.config.commitHistoryLimit;\n let cmd = `log -n ${limit} --format=\"%H|%s|%ai|%an|%ae\"`;\n\n if (since) {\n cmd += ` --since=\"${since.toISOString()}\"`;\n }\n\n try {\n const { stdout } = await this.execGit(cmd);\n\n if (!stdout.trim()) {\n return [];\n }\n\n return stdout\n .trim()\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => this.parseCommitLine(line));\n } catch {\n return [];\n }\n }\n\n /**\n * Get detailed commit information including file changes\n */\n async getCommitDetail(commitHash: string): Promise<CommitDetail | null> {\n try {\n // Get commit info\n const format = '%H|%s|%ai|%an|%ae';\n const { stdout: infoOut } = await this.execGit(\n `show -s --format=\"${format}\" ${commitHash}`\n );\n const commitInfo = this.parseCommitLine(infoOut.trim());\n\n // Get file changes\n const { stdout: diffOut } = await this.execGit(\n `diff-tree --no-commit-id --name-status -r ${commitHash}`\n );\n\n const files = this.parseFileChanges(diffOut);\n let totalAdditions = 0;\n let totalDeletions = 0;\n\n // Get stats for additions/deletions\n try {\n const { stdout: statOut } = await this.execGit(\n `show --stat --format=\"\" ${commitHash}`\n );\n const statMatch = statOut.match(\n /(\\d+) insertions?\\(\\+\\).*?(\\d+) deletions?\\(-\\)/\n );\n if (statMatch) {\n totalAdditions = parseInt(statMatch[1], 10);\n totalDeletions = parseInt(statMatch[2], 10);\n }\n } catch {\n // Stats not critical\n }\n\n return {\n ...commitInfo,\n files,\n totalAdditions,\n totalDeletions,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get commits between two refs (e.g., since a specific commit)\n */\n async getCommitsSince(\n startRef: string,\n endRef: string = 'HEAD',\n filePath?: string\n ): Promise<CommitInfo[]> {\n try {\n const format = '%H|%s|%ai|%an|%ae';\n let cmd = `log --format=\"${format}\" ${startRef}..${endRef}`;\n\n if (filePath) {\n const relativePath = this.getRelativePath(filePath);\n cmd += ` -- \"${relativePath}\"`;\n }\n\n const { stdout } = await this.execGit(cmd);\n\n if (!stdout.trim()) {\n return [];\n }\n\n return stdout\n .trim()\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => this.parseCommitLine(line));\n } catch {\n return [];\n }\n }\n\n // ==========================================================================\n // File Analysis\n // ==========================================================================\n\n /**\n * Get the number of commits for a file\n */\n async getCommitCount(filePath: string): Promise<number> {\n const relativePath = this.getRelativePath(filePath);\n\n try {\n const { stdout } = await this.execGit(\n `rev-list --count HEAD -- \"${relativePath}\"`\n );\n return parseInt(stdout.trim(), 10) || 0;\n } catch {\n return 0;\n }\n }\n\n /**\n * Calculate change frequency for a file based on commit history\n */\n async calculateChangeFrequency(filePath: string): Promise<ChangeFrequency> {\n const commits = await this.getFileCommits(filePath, 50);\n\n if (commits.length < 2) {\n return 'low';\n }\n\n // Calculate average days between commits\n const dates = commits.map((c) => c.date.getTime());\n let totalDays = 0;\n\n for (let i = 1; i < dates.length; i++) {\n totalDays += (dates[i - 1] - dates[i]) / (1000 * 60 * 60 * 24);\n }\n\n const avgDaysBetween = totalDays / (dates.length - 1);\n\n // Classify frequency\n if (avgDaysBetween < 7) return 'high';\n if (avgDaysBetween < 30) return 'medium';\n return 'low';\n }\n\n /**\n * Get files changed in a commit\n */\n async getChangedFiles(commitHash: string): Promise<string[]> {\n try {\n const { stdout } = await this.execGit(\n `diff-tree --no-commit-id --name-only -r ${commitHash}`\n );\n\n return stdout\n .trim()\n .split('\\n')\n .filter((line) => line.trim());\n } catch {\n return [];\n }\n }\n\n /**\n * Find files matching a pattern that were modified since a date\n */\n async findModifiedFiles(\n patterns: string[],\n since: Date\n ): Promise<string[]> {\n try {\n const { stdout } = await this.execGit(\n `log --since=\"${since.toISOString()}\" --name-only --format=\"\" -- ${patterns.map((p) => `\"${p}\"`).join(' ')}`\n );\n\n const files = new Set<string>();\n stdout\n .trim()\n .split('\\n')\n .filter((line) => line.trim())\n .forEach((file) => files.add(file));\n\n return Array.from(files);\n } catch {\n return [];\n }\n }\n\n /**\n * Get the blame information for a file (who last modified each line)\n */\n async getBlameAuthors(filePath: string): Promise<Map<string, number>> {\n const relativePath = this.getRelativePath(filePath);\n const authors = new Map<string, number>();\n\n try {\n const { stdout } = await this.execGit(\n `blame --line-porcelain \"${relativePath}\"`\n );\n\n const matches = stdout.matchAll(/^author (.+)$/gm);\n for (const match of matches) {\n const author = match[1];\n authors.set(author, (authors.get(author) || 0) + 1);\n }\n } catch {\n // File may not exist or have no history\n }\n\n return authors;\n }\n\n // ==========================================================================\n // Branch Information\n // ==========================================================================\n\n /**\n * Get the current branch name\n */\n async getCurrentBranch(): Promise<string> {\n try {\n const { stdout } = await this.execGit('rev-parse --abbrev-ref HEAD');\n return stdout.trim();\n } catch {\n return 'unknown';\n }\n }\n\n /**\n * Get the default branch (main or master)\n */\n async getDefaultBranch(): Promise<string> {\n try {\n const { stdout } = await this.execGit(\n 'symbolic-ref refs/remotes/origin/HEAD'\n );\n const ref = stdout.trim();\n return ref.replace('refs/remotes/origin/', '');\n } catch {\n // Fallback: check if main or master exists\n try {\n await this.execGit('rev-parse --verify main');\n return 'main';\n } catch {\n try {\n await this.execGit('rev-parse --verify master');\n return 'master';\n } catch {\n return 'main';\n }\n }\n }\n }\n\n // ==========================================================================\n // Private Helpers\n // ==========================================================================\n\n private async execGit(command: string): Promise<{ stdout: string; stderr: string }> {\n const fullCommand = `git -C \"${this.repoPath}\" ${command}`;\n return execAsync(fullCommand, { maxBuffer: 10 * 1024 * 1024 });\n }\n\n private getRelativePath(filePath: string): string {\n const absolute = path.isAbsolute(filePath)\n ? filePath\n : path.join(this.repoPath, filePath);\n return path.relative(this.repoPath, absolute);\n }\n\n private parseCommitLine(line: string): CommitInfo {\n const parts = line.split('|');\n return {\n hash: parts[0] || '',\n message: parts[1] || '',\n date: new Date(parts[2] || Date.now()),\n author: parts[3] || 'Unknown',\n email: parts[4],\n };\n }\n\n private parseFileChanges(diffOutput: string): FileChange[] {\n return diffOutput\n .trim()\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => {\n const parts = line.split('\\t');\n const status = parts[0];\n const file = parts[1] || '';\n const oldPath = parts[2]; // For renames\n\n let changeType: FileChange['changeType'] = 'modified';\n if (status === 'A') changeType = 'added';\n else if (status === 'D') changeType = 'deleted';\n else if (status.startsWith('R')) changeType = 'renamed';\n\n return {\n file: changeType === 'renamed' ? (oldPath || file) : file,\n additions: 0, // Would need --numstat for this\n deletions: 0,\n changeType,\n oldPath: changeType === 'renamed' ? file : undefined,\n };\n });\n }\n}\n\n// Singleton instance\nlet gitHistoryAnalyzerInstance: GitHistoryAnalyzer | null = null;\n\n/**\n * Get the singleton GitHistoryAnalyzer instance\n */\nexport function getGitHistoryAnalyzer(\n repoPath?: string,\n config?: Partial<GitAnalysisConfig>\n): GitHistoryAnalyzer {\n if (!gitHistoryAnalyzerInstance && repoPath) {\n gitHistoryAnalyzerInstance = new GitHistoryAnalyzer(repoPath, config);\n }\n if (!gitHistoryAnalyzerInstance) {\n throw new Error('GitHistoryAnalyzer not initialized. Provide repoPath.');\n }\n return gitHistoryAnalyzerInstance;\n}\n\n/**\n * Reset the singleton instance (useful for testing)\n */\nexport function resetGitHistoryAnalyzer(): void {\n gitHistoryAnalyzerInstance = null;\n}\n","/**\n * Documentation Freshness Analyzer\n *\n * Analyzes git history to determine documentation freshness,\n * identify stale documents, and calculate freshness scores.\n */\n\nimport { GitHistoryAnalyzer } from './git-history-analyzer.js';\nimport {\n DEFAULT_GIT_ANALYSIS_CONFIG,\n type FreshnessResult,\n type StaleDoc,\n type ChangeFrequency,\n type GitAnalysisConfig,\n} from './types.js';\n\n/**\n * DocFreshnessAnalyzer calculates freshness scores and identifies\n * stale documentation based on git history.\n */\nexport class DocFreshnessAnalyzer {\n private gitAnalyzer: GitHistoryAnalyzer;\n private config: GitAnalysisConfig;\n private freshnessCache: Map<string, FreshnessResult> = new Map();\n\n constructor(\n gitAnalyzer: GitHistoryAnalyzer,\n config: Partial<GitAnalysisConfig> = {}\n ) {\n this.gitAnalyzer = gitAnalyzer;\n this.config = { ...DEFAULT_GIT_ANALYSIS_CONFIG, ...config };\n }\n\n // ==========================================================================\n // Freshness Analysis\n // ==========================================================================\n\n /**\n * Get the freshness result for a specific document\n */\n async getDocFreshness(docPath: string): Promise<FreshnessResult> {\n // Check cache first\n if (this.freshnessCache.has(docPath)) {\n return this.freshnessCache.get(docPath)!;\n }\n\n const lastCommit = await this.gitAnalyzer.getLastCommit(docPath);\n\n if (!lastCommit) {\n // File has no git history - treat as new/fresh\n const result: FreshnessResult = {\n file: docPath,\n lastModified: new Date(),\n daysSinceUpdate: 0,\n lastAuthor: 'Unknown',\n lastCommitMessage: 'No git history',\n changeFrequency: 'low',\n freshnessScore: 50, // Neutral score for unknown history\n totalCommits: 0,\n };\n this.freshnessCache.set(docPath, result);\n return result;\n }\n\n const daysSinceUpdate = this.calculateDaysSince(lastCommit.date);\n const changeFrequency = await this.gitAnalyzer.calculateChangeFrequency(docPath);\n const totalCommits = await this.gitAnalyzer.getCommitCount(docPath);\n\n const result: FreshnessResult = {\n file: docPath,\n lastModified: lastCommit.date,\n daysSinceUpdate,\n lastAuthor: lastCommit.author,\n lastCommitMessage: lastCommit.message,\n changeFrequency,\n freshnessScore: this.calculateFreshnessScore(daysSinceUpdate, changeFrequency),\n totalCommits,\n };\n\n this.freshnessCache.set(docPath, result);\n return result;\n }\n\n /**\n * Find all stale documents (not updated in threshold days)\n */\n async findStaleDocuments(\n docPaths: string[],\n thresholdDays?: number\n ): Promise<StaleDoc[]> {\n const threshold = thresholdDays ?? this.config.staleThresholdDays;\n const staleDocs: StaleDoc[] = [];\n\n for (const docPath of docPaths) {\n const freshness = await this.getDocFreshness(docPath);\n\n if (freshness.daysSinceUpdate > threshold) {\n const staleness = this.classifyStaleness(freshness.daysSinceUpdate, threshold);\n\n staleDocs.push({\n file: docPath,\n daysSinceUpdate: freshness.daysSinceUpdate,\n lastAuthor: freshness.lastAuthor,\n lastCommitMessage: freshness.lastCommitMessage,\n relatedCodeFiles: [], // Will be populated by CodeDocSyncDetector\n staleness,\n });\n }\n }\n\n // Sort by staleness severity and days\n return staleDocs.sort((a, b) => {\n const severityOrder = { critical: 0, high: 1, medium: 2 };\n const severityDiff = severityOrder[a.staleness] - severityOrder[b.staleness];\n if (severityDiff !== 0) return severityDiff;\n return b.daysSinceUpdate - a.daysSinceUpdate;\n });\n }\n\n /**\n * Get freshness scores for multiple documents\n */\n async getBulkFreshness(docPaths: string[]): Promise<Map<string, FreshnessResult>> {\n const results = new Map<string, FreshnessResult>();\n\n // Process in parallel batches\n const batchSize = 10;\n for (let i = 0; i < docPaths.length; i += batchSize) {\n const batch = docPaths.slice(i, i + batchSize);\n const batchResults = await Promise.all(\n batch.map((path) => this.getDocFreshness(path))\n );\n\n batchResults.forEach((result, idx) => {\n results.set(batch[idx], result);\n });\n }\n\n return results;\n }\n\n /**\n * Calculate average freshness score for a set of documents\n */\n async calculateAverageFreshness(docPaths: string[]): Promise<number> {\n if (docPaths.length === 0) return 0;\n\n const freshnessResults = await this.getBulkFreshness(docPaths);\n let totalScore = 0;\n\n for (const result of freshnessResults.values()) {\n totalScore += result.freshnessScore;\n }\n\n return Math.round(totalScore / freshnessResults.size);\n }\n\n /**\n * Get documents sorted by freshness (least fresh first)\n */\n async getDocumentsByFreshness(\n docPaths: string[]\n ): Promise<FreshnessResult[]> {\n const freshnessResults = await this.getBulkFreshness(docPaths);\n return Array.from(freshnessResults.values()).sort(\n (a, b) => a.freshnessScore - b.freshnessScore\n );\n }\n\n // ==========================================================================\n // Freshness Scoring\n // ==========================================================================\n\n /**\n * Calculate freshness score (0-100, higher = fresher)\n */\n private calculateFreshnessScore(\n daysSinceUpdate: number,\n changeFrequency: ChangeFrequency\n ): number {\n // Base score from days since update (decay curve)\n let score: number;\n\n if (daysSinceUpdate <= 7) {\n score = 100; // Very fresh\n } else if (daysSinceUpdate <= 30) {\n score = 100 - ((daysSinceUpdate - 7) / 23) * 20; // 80-100\n } else if (daysSinceUpdate <= 90) {\n score = 80 - ((daysSinceUpdate - 30) / 60) * 30; // 50-80\n } else if (daysSinceUpdate <= 180) {\n score = 50 - ((daysSinceUpdate - 90) / 90) * 25; // 25-50\n } else if (daysSinceUpdate <= 365) {\n score = 25 - ((daysSinceUpdate - 180) / 185) * 15; // 10-25\n } else {\n score = Math.max(0, 10 - (daysSinceUpdate - 365) / 100); // 0-10\n }\n\n // Adjust based on change frequency\n // Frequently updated docs are \"expected\" to be fresh\n // Infrequently updated docs get a slight boost (they may be stable)\n const frequencyAdjustment: Record<ChangeFrequency, number> = {\n high: 0, // No adjustment - should be fresh\n medium: 5, // Small boost\n low: 10, // Larger boost - may be stable reference docs\n };\n\n score += frequencyAdjustment[changeFrequency];\n\n return Math.min(100, Math.max(0, Math.round(score)));\n }\n\n /**\n * Classify staleness severity\n */\n private classifyStaleness(\n daysSinceUpdate: number,\n threshold: number\n ): 'critical' | 'high' | 'medium' {\n const ratio = daysSinceUpdate / threshold;\n\n if (ratio >= 3) return 'critical'; // 3x+ threshold\n if (ratio >= 2) return 'high'; // 2x-3x threshold\n return 'medium'; // 1x-2x threshold\n }\n\n /**\n * Calculate days since a date\n */\n private calculateDaysSince(date: Date): number {\n const now = Date.now();\n const then = date.getTime();\n return Math.floor((now - then) / (1000 * 60 * 60 * 24));\n }\n\n // ==========================================================================\n // Cache Management\n // ==========================================================================\n\n /**\n * Clear the freshness cache\n */\n clearCache(): void {\n this.freshnessCache.clear();\n }\n\n /**\n * Remove a specific entry from the cache\n */\n invalidateCache(docPath: string): void {\n this.freshnessCache.delete(docPath);\n }\n}\n\n// Singleton instance\nlet docFreshnessAnalyzerInstance: DocFreshnessAnalyzer | null = null;\n\n/**\n * Get the singleton DocFreshnessAnalyzer instance\n */\nexport function getDocFreshnessAnalyzer(\n gitAnalyzer?: GitHistoryAnalyzer,\n config?: Partial<GitAnalysisConfig>\n): DocFreshnessAnalyzer {\n if (!docFreshnessAnalyzerInstance && gitAnalyzer) {\n docFreshnessAnalyzerInstance = new DocFreshnessAnalyzer(gitAnalyzer, config);\n }\n if (!docFreshnessAnalyzerInstance) {\n throw new Error('DocFreshnessAnalyzer not initialized. Provide gitAnalyzer.');\n }\n return docFreshnessAnalyzerInstance;\n}\n\n/**\n * Reset the singleton instance\n */\nexport function resetDocFreshnessAnalyzer(): void {\n docFreshnessAnalyzerInstance = null;\n}\n","/**\n * Code-Doc Sync Detector\n *\n * Detects desynchronization between code and documentation by analyzing\n * git history patterns, identifying undocumented changes, and calculating\n * drift risk scores.\n */\n\nimport { GitHistoryAnalyzer } from './git-history-analyzer.js';\nimport { DocFreshnessAnalyzer } from './doc-freshness-analyzer.js';\nimport {\n DEFAULT_GIT_ANALYSIS_CONFIG,\n type DesyncResult,\n type DesyncRisk,\n type UndocumentedChange,\n type DriftRiskScore,\n type DriftRiskFactors,\n type RiskArea,\n type GitAnalysisConfig,\n type CommitInfo,\n} from './types.js';\n\n/**\n * CodeDocSyncDetector identifies mismatches between code changes\n * and documentation updates, helping predict documentation drift.\n */\nexport class CodeDocSyncDetector {\n private gitAnalyzer: GitHistoryAnalyzer;\n private freshnessAnalyzer: DocFreshnessAnalyzer;\n private config: GitAnalysisConfig;\n\n constructor(\n gitAnalyzer: GitHistoryAnalyzer,\n freshnessAnalyzer: DocFreshnessAnalyzer,\n config: Partial<GitAnalysisConfig> = {}\n ) {\n this.gitAnalyzer = gitAnalyzer;\n this.freshnessAnalyzer = freshnessAnalyzer;\n this.config = { ...DEFAULT_GIT_ANALYSIS_CONFIG, ...config };\n }\n\n // ==========================================================================\n // Desync Detection\n // ==========================================================================\n\n /**\n * Check if code and documentation are desynchronized\n */\n async detectDocCodeDesync(\n codePath: string,\n docPath: string\n ): Promise<DesyncResult> {\n const [codeCommit, docCommit] = await Promise.all([\n this.gitAnalyzer.getLastCommit(codePath),\n this.gitAnalyzer.getLastCommit(docPath),\n ]);\n\n const codeDate = codeCommit?.date || new Date(0);\n const docDate = docCommit?.date || new Date(0);\n\n const daysBetween = Math.abs(\n Math.floor((codeDate.getTime() - docDate.getTime()) / (1000 * 60 * 60 * 24))\n );\n\n // Get code changes since doc was last updated\n let codeChanges: CommitInfo[] = [];\n let commitsSinceDocUpdate = 0;\n\n if (docCommit && codeDate > docDate) {\n codeChanges = await this.gitAnalyzer.getCommitsSince(\n docCommit.hash,\n 'HEAD',\n codePath\n );\n commitsSinceDocUpdate = codeChanges.length;\n }\n\n const desyncRisk = this.calculateDesyncRisk(daysBetween, commitsSinceDocUpdate);\n\n return {\n codePath,\n docPath,\n codeLastModified: codeDate,\n docLastModified: docDate,\n daysBetween,\n desyncRisk,\n codeChanges,\n commitsSinceDocUpdate,\n recommendation: this.generateDesyncRecommendation(\n daysBetween,\n commitsSinceDocUpdate,\n desyncRisk\n ),\n };\n }\n\n /**\n * Find code changes that likely need documentation updates\n */\n async findUndocumentedChanges(\n codePaths: string[],\n docPaths: string[],\n since?: Date\n ): Promise<UndocumentedChange[]> {\n const sinceDate = since || this.getDefaultSinceDate();\n const undocumented: UndocumentedChange[] = [];\n\n // Get all recent commits for code files\n const commits = await this.gitAnalyzer.getAllCommits(\n this.config.commitHistoryLimit,\n sinceDate\n );\n\n // Build a set of doc paths for quick lookup\n const docPathSet = new Set(docPaths.map((p) => p.toLowerCase()));\n\n // Check each commit for code changes without corresponding doc changes\n for (const commit of commits) {\n const detail = await this.gitAnalyzer.getCommitDetail(commit.hash);\n if (!detail) continue;\n\n const codeFilesChanged: string[] = [];\n let hasDocChange = false;\n\n for (const file of detail.files) {\n if (this.isCodeFile(file.file)) {\n codeFilesChanged.push(file.file);\n }\n if (this.isDocFile(file.file)) {\n hasDocChange = true;\n }\n }\n\n // If code changed but no docs changed, this might need documentation\n if (codeFilesChanged.length > 0 && !hasDocChange) {\n for (const codeFile of codeFilesChanged) {\n // Find related documentation files\n const relatedDocs = await this.findRelatedDocs(codeFile, docPaths);\n\n if (relatedDocs.length > 0) {\n const severity = this.classifyChangeSeverity(commit, detail);\n\n undocumented.push({\n file: codeFile,\n commit,\n relatedDocs,\n severity,\n reason: this.generateUndocumentedReason(commit, codeFile),\n });\n }\n }\n }\n }\n\n return undocumented.sort((a, b) => {\n const severityOrder = { high: 0, medium: 1, low: 2 };\n return severityOrder[a.severity] - severityOrder[b.severity];\n });\n }\n\n // ==========================================================================\n // Drift Risk Scoring\n // ==========================================================================\n\n /**\n * Calculate drift risk score for a file\n */\n async calculateDriftRisk(\n filePath: string,\n relatedDocPaths: string[]\n ): Promise<DriftRiskScore> {\n const factors = await this.calculateRiskFactors(filePath, relatedDocPaths);\n const riskScore = this.computeRiskScore(factors);\n const riskLevel = this.classifyRiskLevel(riskScore);\n\n return {\n file: filePath,\n riskScore,\n factors,\n riskLevel,\n recommendation: this.generateRiskRecommendation(riskLevel, factors),\n };\n }\n\n /**\n * Get high-risk areas in the codebase\n */\n async getHighRiskAreas(\n codePaths: string[],\n docPaths: string[]\n ): Promise<RiskArea[]> {\n const riskScores: DriftRiskScore[] = [];\n\n // Calculate risk for each code file\n for (const codePath of codePaths) {\n const relatedDocs = await this.findRelatedDocs(codePath, docPaths);\n const risk = await this.calculateDriftRisk(codePath, relatedDocs);\n riskScores.push(risk);\n }\n\n // Group by directory and identify high-risk areas\n const directoryRisks = new Map<string, DriftRiskScore[]>();\n\n for (const risk of riskScores) {\n const dir = this.getDirectory(risk.file);\n if (!directoryRisks.has(dir)) {\n directoryRisks.set(dir, []);\n }\n directoryRisks.get(dir)!.push(risk);\n }\n\n // Create risk areas for directories with high average risk\n const areas: RiskArea[] = [];\n\n for (const [dir, risks] of directoryRisks) {\n const avgScore =\n risks.reduce((sum, r) => sum + r.riskScore, 0) / risks.length;\n\n if (avgScore >= 50) {\n // Only include high-risk areas\n const patterns = this.identifyRiskPatterns(risks);\n\n areas.push({\n files: risks.map((r) => r.file),\n averageRiskScore: Math.round(avgScore),\n riskLevel: this.classifyRiskLevel(avgScore),\n patterns,\n recommendation: this.generateAreaRecommendation(dir, patterns),\n });\n }\n }\n\n return areas.sort((a, b) => b.averageRiskScore - a.averageRiskScore);\n }\n\n // ==========================================================================\n // Private Helpers - Desync\n // ==========================================================================\n\n private calculateDesyncRisk(\n daysBetween: number,\n changeCount: number\n ): DesyncRisk {\n if (daysBetween > 90 || changeCount > 10) return 'high';\n if (daysBetween > 30 || changeCount > 5) return 'medium';\n return 'low';\n }\n\n private generateDesyncRecommendation(\n daysBetween: number,\n changeCount: number,\n risk: DesyncRisk\n ): string {\n if (risk === 'high') {\n if (changeCount > 10) {\n return `Documentation is significantly out of date. ${changeCount} code changes have been made since the last doc update. Priority review recommended.`;\n }\n return `Documentation hasn't been updated in ${daysBetween} days. Review for accuracy immediately.`;\n }\n\n if (risk === 'medium') {\n if (changeCount > 5) {\n return `Consider reviewing documentation - ${changeCount} code changes since last doc update.`;\n }\n return `Documentation may be slightly out of date (${daysBetween} days since update). Review when possible.`;\n }\n\n return 'Documentation appears to be in sync with code.';\n }\n\n // ==========================================================================\n // Private Helpers - Risk Scoring\n // ==========================================================================\n\n private async calculateRiskFactors(\n filePath: string,\n relatedDocPaths: string[]\n ): Promise<DriftRiskFactors> {\n // Doc freshness factor\n let docFreshness = 100; // Default to fresh if no related docs\n if (relatedDocPaths.length > 0) {\n const avgFreshness =\n await this.freshnessAnalyzer.calculateAverageFreshness(relatedDocPaths);\n docFreshness = 100 - avgFreshness; // Invert: lower freshness = higher risk\n }\n\n // Code change frequency\n const changeFreq = await this.gitAnalyzer.calculateChangeFrequency(filePath);\n const codeChangeFrequency: number =\n changeFreq === 'high' ? 80 : changeFreq === 'medium' ? 50 : 20;\n\n // Historical drift rate (simplified - based on desync history)\n const historicalDriftRate = await this.estimateHistoricalDrift(\n filePath,\n relatedDocPaths\n );\n\n // File complexity (simplified - based on commit count as proxy)\n const commitCount = await this.gitAnalyzer.getCommitCount(filePath);\n const fileComplexity = Math.min(100, commitCount * 2);\n\n return {\n docFreshness,\n codeChangeFrequency,\n historicalDriftRate,\n fileComplexity,\n };\n }\n\n private computeRiskScore(factors: DriftRiskFactors): number {\n const { riskWeights } = this.config;\n\n const score =\n factors.docFreshness * riskWeights.docFreshness +\n factors.codeChangeFrequency * riskWeights.codeChangeFrequency +\n factors.historicalDriftRate * riskWeights.historicalDriftRate +\n factors.fileComplexity * riskWeights.fileComplexity;\n\n return Math.min(100, Math.max(0, Math.round(score)));\n }\n\n private classifyRiskLevel(\n score: number\n ): 'critical' | 'high' | 'medium' | 'low' {\n if (score >= 80) return 'critical';\n if (score >= 60) return 'high';\n if (score >= 40) return 'medium';\n return 'low';\n }\n\n private async estimateHistoricalDrift(\n codePath: string,\n docPaths: string[]\n ): Promise<number> {\n if (docPaths.length === 0) return 50; // Neutral if no docs\n\n // Check how often code changed without doc updates\n const codeCommits = await this.gitAnalyzer.getFileCommits(codePath, 20);\n const docCommitDates = new Set<string>();\n\n for (const docPath of docPaths) {\n const docCommits = await this.gitAnalyzer.getFileCommits(docPath, 20);\n for (const commit of docCommits) {\n // Use date string to group by day\n docCommitDates.add(commit.date.toISOString().split('T')[0]);\n }\n }\n\n // Count code commits that happened without doc commits on the same day\n let unmatchedCodeCommits = 0;\n for (const commit of codeCommits) {\n const dateStr = commit.date.toISOString().split('T')[0];\n if (!docCommitDates.has(dateStr)) {\n unmatchedCodeCommits++;\n }\n }\n\n // Calculate drift rate as percentage\n return Math.round((unmatchedCodeCommits / Math.max(1, codeCommits.length)) * 100);\n }\n\n private generateRiskRecommendation(\n level: 'critical' | 'high' | 'medium' | 'low',\n factors: DriftRiskFactors\n ): string {\n if (level === 'critical') {\n return 'Critical drift risk: Immediate documentation review required.';\n }\n\n if (level === 'high') {\n if (factors.docFreshness > 70) {\n return 'Documentation appears stale. Schedule review to update.';\n }\n if (factors.codeChangeFrequency > 70) {\n return 'Frequent code changes increase drift risk. Consider doc automation.';\n }\n return 'High drift risk detected. Review documentation soon.';\n }\n\n if (level === 'medium') {\n return 'Moderate drift risk. Monitor for documentation accuracy.';\n }\n\n return 'Low drift risk. Documentation appears well maintained.';\n }\n\n // ==========================================================================\n // Private Helpers - Utilities\n // ==========================================================================\n\n private isCodeFile(filePath: string): boolean {\n const codeExtensions = [\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.py',\n '.go',\n '.rs',\n '.java',\n '.c',\n '.cpp',\n '.cs',\n ];\n return codeExtensions.some((ext) => filePath.toLowerCase().endsWith(ext));\n }\n\n private isDocFile(filePath: string): boolean {\n const docExtensions = ['.md', '.mdx', '.rst', '.txt', '.adoc'];\n const docDirs = ['docs', 'documentation', 'doc'];\n const lowerPath = filePath.toLowerCase();\n\n return (\n docExtensions.some((ext) => lowerPath.endsWith(ext)) ||\n docDirs.some((dir) => lowerPath.includes(`/${dir}/`))\n );\n }\n\n private async findRelatedDocs(\n codePath: string,\n docPaths: string[]\n ): Promise<string[]> {\n const related: string[] = [];\n const codeBasename = this.getBasename(codePath).toLowerCase();\n const codeDir = this.getDirectory(codePath).toLowerCase();\n\n for (const docPath of docPaths) {\n const docContent = this.getBasename(docPath).toLowerCase();\n const docDir = this.getDirectory(docPath).toLowerCase();\n\n // Match by name similarity\n if (\n docContent.includes(codeBasename.replace(/\\.(ts|js|py|go)x?$/, '')) ||\n codeBasename.includes(docContent.replace(/\\.md$/, ''))\n ) {\n related.push(docPath);\n continue;\n }\n\n // Match by directory proximity\n if (docDir.includes(codeDir) || codeDir.includes(docDir)) {\n related.push(docPath);\n continue;\n }\n\n // Match API/README patterns\n if (\n (codeDir.includes('api') && docPath.toLowerCase().includes('api')) ||\n (codePath.includes('index') && docPath.toLowerCase().includes('readme'))\n ) {\n related.push(docPath);\n }\n }\n\n return related;\n }\n\n private classifyChangeSeverity(\n commit: CommitInfo,\n detail: { totalAdditions: number; totalDeletions: number }\n ): 'high' | 'medium' | 'low' {\n const message = commit.message.toLowerCase();\n\n // High severity indicators\n if (\n message.includes('breaking') ||\n message.includes('api change') ||\n message.includes('major') ||\n message.includes('deprecat')\n ) {\n return 'high';\n }\n\n // Large changes\n if (detail.totalAdditions + detail.totalDeletions > 100) {\n return 'high';\n }\n\n // Medium severity indicators\n if (\n message.includes('feat') ||\n message.includes('add') ||\n message.includes('remove') ||\n message.includes('change')\n ) {\n return 'medium';\n }\n\n // Medium-sized changes\n if (detail.totalAdditions + detail.totalDeletions > 30) {\n return 'medium';\n }\n\n return 'low';\n }\n\n private generateUndocumentedReason(\n commit: CommitInfo,\n codeFile: string\n ): string {\n const message = commit.message.toLowerCase();\n\n if (message.includes('feat') || message.includes('add')) {\n return `New feature added in ${codeFile} may need documentation.`;\n }\n if (message.includes('fix')) {\n return `Bug fix in ${codeFile} may affect documented behavior.`;\n }\n if (message.includes('refactor')) {\n return `Refactoring in ${codeFile} may change API/usage patterns.`;\n }\n if (message.includes('breaking') || message.includes('api')) {\n return `API changes in ${codeFile} require documentation updates.`;\n }\n\n return `Code change in ${codeFile} should be reviewed for documentation impact.`;\n }\n\n private identifyRiskPatterns(risks: DriftRiskScore[]): string[] {\n const patterns: string[] = [];\n\n const avgDocFreshness =\n risks.reduce((s, r) => s + r.factors.docFreshness, 0) / risks.length;\n const avgChangeFreq =\n risks.reduce((s, r) => s + r.factors.codeChangeFrequency, 0) / risks.length;\n\n if (avgDocFreshness > 60) {\n patterns.push('Stale documentation');\n }\n if (avgChangeFreq > 60) {\n patterns.push('Frequent code changes');\n }\n if (risks.length > 5) {\n patterns.push('Large number of files at risk');\n }\n\n return patterns;\n }\n\n private generateAreaRecommendation(\n directory: string,\n patterns: string[]\n ): string {\n if (patterns.includes('Stale documentation')) {\n return `Schedule documentation review for ${directory}`;\n }\n if (patterns.includes('Frequent code changes')) {\n return `Consider doc automation for ${directory} due to frequent changes`;\n }\n return `Review documentation coverage for ${directory}`;\n }\n\n private getBasename(filePath: string): string {\n const parts = filePath.split('/');\n return parts[parts.length - 1] || filePath;\n }\n\n private getDirectory(filePath: string): string {\n const parts = filePath.split('/');\n return parts.slice(0, -1).join('/') || '.';\n }\n\n private getDefaultSinceDate(): Date {\n const date = new Date();\n date.setDate(date.getDate() - 30); // Default to 30 days ago\n return date;\n }\n}\n\n// Singleton instance\nlet codeDocSyncDetectorInstance: CodeDocSyncDetector | null = null;\n\n/**\n * Get the singleton CodeDocSyncDetector instance\n */\nexport function getCodeDocSyncDetector(\n gitAnalyzer?: GitHistoryAnalyzer,\n freshnessAnalyzer?: DocFreshnessAnalyzer,\n config?: Partial<GitAnalysisConfig>\n): CodeDocSyncDetector {\n if (!codeDocSyncDetectorInstance && gitAnalyzer && freshnessAnalyzer) {\n codeDocSyncDetectorInstance = new CodeDocSyncDetector(\n gitAnalyzer,\n freshnessAnalyzer,\n config\n );\n }\n if (!codeDocSyncDetectorInstance) {\n throw new Error(\n 'CodeDocSyncDetector not initialized. Provide gitAnalyzer and freshnessAnalyzer.'\n );\n }\n return codeDocSyncDetectorInstance;\n}\n\n/**\n * Reset the singleton instance\n */\nexport function resetCodeDocSyncDetector(): void {\n codeDocSyncDetectorInstance = null;\n}\n","/**\n * Git History Analysis Module\n *\n * Provides git-based analysis for documentation freshness,\n * code-doc desync detection, and drift risk prediction.\n *\n * Key Features:\n * - Documentation freshness scoring\n * - Code-doc desynchronization detection\n * - Drift risk prediction based on change patterns\n * - Undocumented change identification\n */\n\n// Types\nexport type {\n CommitInfo,\n CommitDetail,\n FileChange,\n ChangeFrequency,\n FreshnessResult,\n StaleDoc,\n DesyncRisk,\n DesyncResult,\n UndocumentedChange,\n DriftRiskFactors,\n DriftRiskScore,\n RiskArea,\n GitAnalysisConfig,\n GitAnalysisResult,\n} from './types.js';\n\nexport { DEFAULT_GIT_ANALYSIS_CONFIG } from './types.js';\n\n// Git History Analyzer\nexport {\n GitHistoryAnalyzer,\n getGitHistoryAnalyzer,\n resetGitHistoryAnalyzer,\n} from './git-history-analyzer.js';\n\n// Doc Freshness Analyzer\nexport {\n DocFreshnessAnalyzer,\n getDocFreshnessAnalyzer,\n resetDocFreshnessAnalyzer,\n} from './doc-freshness-analyzer.js';\n\n// Code-Doc Sync Detector\nexport {\n CodeDocSyncDetector,\n getCodeDocSyncDetector,\n resetCodeDocSyncDetector,\n} from './code-doc-sync-detector.js';\n\n// ==========================================================================\n// Convenience Functions\n// ==========================================================================\n\nimport { GitHistoryAnalyzer } from './git-history-analyzer.js';\nimport { DocFreshnessAnalyzer } from './doc-freshness-analyzer.js';\nimport { CodeDocSyncDetector } from './code-doc-sync-detector.js';\nimport type {\n GitAnalysisConfig,\n GitAnalysisResult,\n FreshnessResult,\n DesyncResult,\n DriftRiskScore,\n} from './types.js';\n\n/**\n * Initialize all git analysis components for a repository\n */\nexport function initializeGitAnalysis(\n repoPath: string,\n config?: Partial<GitAnalysisConfig>\n): {\n gitAnalyzer: GitHistoryAnalyzer;\n freshnessAnalyzer: DocFreshnessAnalyzer;\n syncDetector: CodeDocSyncDetector;\n} {\n const gitAnalyzer = new GitHistoryAnalyzer(repoPath, config);\n const freshnessAnalyzer = new DocFreshnessAnalyzer(gitAnalyzer, config);\n const syncDetector = new CodeDocSyncDetector(\n gitAnalyzer,\n freshnessAnalyzer,\n config\n );\n\n return { gitAnalyzer, freshnessAnalyzer, syncDetector };\n}\n\n/**\n * Run a full git analysis on a repository\n */\nexport async function runFullGitAnalysis(\n repoPath: string,\n docPaths: string[],\n codePaths: string[],\n config?: Partial<GitAnalysisConfig>\n): Promise<GitAnalysisResult> {\n const { gitAnalyzer, freshnessAnalyzer, syncDetector } = initializeGitAnalysis(\n repoPath,\n config\n );\n\n // Check if valid git repo\n const isValid = await gitAnalyzer.isValidGitRepo();\n if (!isValid) {\n return createEmptyResult(repoPath);\n }\n\n // Run freshness analysis\n const staleDocuments = await freshnessAnalyzer.findStaleDocuments(docPaths);\n const freshnessScores = await freshnessAnalyzer.getBulkFreshness(docPaths);\n const averageFreshness =\n await freshnessAnalyzer.calculateAverageFreshness(docPaths);\n\n // Run desync analysis\n const desyncPairs: DesyncResult[] = [];\n for (const codePath of codePaths.slice(0, 20)) {\n // Limit for performance\n for (const docPath of docPaths.slice(0, 10)) {\n const desync = await syncDetector.detectDocCodeDesync(codePath, docPath);\n if (desync.desyncRisk !== 'low') {\n desyncPairs.push(desync);\n }\n }\n }\n\n const undocumentedChanges = await syncDetector.findUndocumentedChanges(\n codePaths,\n docPaths\n );\n\n const overallDesyncRisk = calculateOverallDesyncRisk(desyncPairs);\n\n // Run drift risk analysis\n const fileScores: DriftRiskScore[] = [];\n for (const codePath of codePaths.slice(0, 20)) {\n // Limit for performance\n const score = await syncDetector.calculateDriftRisk(codePath, docPaths);\n fileScores.push(score);\n }\n\n const highRiskAreas = await syncDetector.getHighRiskAreas(codePaths, docPaths);\n\n const overallRiskScore =\n fileScores.length > 0\n ? Math.round(\n fileScores.reduce((s, f) => s + f.riskScore, 0) / fileScores.length\n )\n : 0;\n\n return {\n repoPath,\n analyzedAt: new Date(),\n freshness: {\n staleDocuments,\n freshnessScores,\n averageFreshness,\n },\n desync: {\n desyncPairs,\n undocumentedChanges,\n overallDesyncRisk,\n },\n driftRisk: {\n fileScores,\n highRiskAreas,\n overallRiskScore,\n },\n summary: {\n totalDocsAnalyzed: docPaths.length,\n totalCodeFilesAnalyzed: codePaths.length,\n staleDocCount: staleDocuments.length,\n desyncPairCount: desyncPairs.length,\n highRiskFileCount: fileScores.filter((s) => s.riskLevel === 'high' || s.riskLevel === 'critical').length,\n },\n };\n}\n\n/**\n * Quick freshness check for a single document\n */\nexport async function quickFreshnessCheck(\n repoPath: string,\n docPath: string\n): Promise<FreshnessResult | null> {\n try {\n const gitAnalyzer = new GitHistoryAnalyzer(repoPath);\n const isValid = await gitAnalyzer.isValidGitRepo();\n\n if (!isValid) {\n return null;\n }\n\n const freshnessAnalyzer = new DocFreshnessAnalyzer(gitAnalyzer);\n return await freshnessAnalyzer.getDocFreshness(docPath);\n } catch {\n return null;\n }\n}\n\n/**\n * Quick desync check between a code file and doc file\n */\nexport async function quickDesyncCheck(\n repoPath: string,\n codePath: string,\n docPath: string\n): Promise<DesyncResult | null> {\n try {\n const { syncDetector, gitAnalyzer } = initializeGitAnalysis(repoPath);\n const isValid = await gitAnalyzer.isValidGitRepo();\n\n if (!isValid) {\n return null;\n }\n\n return await syncDetector.detectDocCodeDesync(codePath, docPath);\n } catch {\n return null;\n }\n}\n\n// ==========================================================================\n// Private Helpers\n// ==========================================================================\n\nfunction createEmptyResult(repoPath: string): GitAnalysisResult {\n return {\n repoPath,\n analyzedAt: new Date(),\n freshness: {\n staleDocuments: [],\n freshnessScores: new Map(),\n averageFreshness: 0,\n },\n desync: {\n desyncPairs: [],\n undocumentedChanges: [],\n overallDesyncRisk: 'low',\n },\n driftRisk: {\n fileScores: [],\n highRiskAreas: [],\n overallRiskScore: 0,\n },\n summary: {\n totalDocsAnalyzed: 0,\n totalCodeFilesAnalyzed: 0,\n staleDocCount: 0,\n desyncPairCount: 0,\n highRiskFileCount: 0,\n },\n };\n}\n\nfunction calculateOverallDesyncRisk(\n pairs: DesyncResult[]\n): 'high' | 'medium' | 'low' {\n if (pairs.length === 0) return 'low';\n\n const highCount = pairs.filter((p) => p.desyncRisk === 'high').length;\n const mediumCount = pairs.filter((p) => p.desyncRisk === 'medium').length;\n\n if (highCount > pairs.length * 0.3) return 'high';\n if (highCount + mediumCount > pairs.length * 0.5) return 'medium';\n return 'low';\n}\n","/**\n * Confidence Calibration Types\n *\n * Types for tracking predictions, recording outcomes, and\n * calibrating confidence scores based on historical accuracy.\n */\n\nimport type { VerificationStatus, RequirementCategory } from '../agents/types.js';\n\n// ============================================================================\n// Prediction Types\n// ============================================================================\n\nexport interface Prediction {\n /** Unique prediction ID */\n id: string;\n\n /** Predicted verification status */\n status: VerificationStatus;\n\n /** Raw confidence score (0-100) */\n confidence: number;\n\n /** Requirement category */\n category: RequirementCategory;\n\n /** Framework context */\n framework?: string;\n\n /** Pattern key if matched */\n patternKey?: string;\n\n /** Timestamp */\n timestamp: Date;\n}\n\nexport interface PredictionContext {\n /** Project size category */\n projectSize: 'small' | 'medium' | 'large' | 'enterprise';\n\n /** Type of documentation */\n docType: 'prd' | 'api' | 'architecture' | 'readme' | 'other';\n\n /** Type of code */\n codeType: 'frontend' | 'backend' | 'fullstack' | 'library' | 'other';\n\n /** Language(s) */\n languages: string[];\n}\n\n// ============================================================================\n// Outcome Types\n// ============================================================================\n\nexport interface Outcome {\n /** Actual verification status after review */\n status: VerificationStatus;\n\n /** User feedback/reason for correction */\n userFeedback?: string;\n\n /** Who provided the outcome (user ID or 'system') */\n source: string;\n\n /** Timestamp of feedback */\n timestamp: Date;\n}\n\n// ============================================================================\n// Calibration Record\n// ============================================================================\n\nexport interface CalibrationRecord {\n /** Unique record ID */\n id: string;\n\n /** When the prediction was made */\n predictionTimestamp: Date;\n\n /** When the outcome was recorded */\n outcomeTimestamp?: Date;\n\n /** The prediction details */\n prediction: {\n status: VerificationStatus;\n confidence: number;\n category: RequirementCategory;\n framework?: string;\n patternKey?: string;\n };\n\n /** The actual outcome (once known) */\n outcome?: {\n status: VerificationStatus;\n wasCorrect: boolean;\n userFeedback?: string;\n source: string;\n };\n\n /** Context for learning */\n context: PredictionContext;\n\n /** Whether this record has been used for calibration */\n calibrated: boolean;\n}\n\n// ============================================================================\n// Calibration Bucket\n// ============================================================================\n\nexport interface CalibrationBucket {\n /** Confidence range [min, max) */\n confidenceRange: [number, number];\n\n /** Average confidence in this bucket */\n predictedAccuracy: number;\n\n /** Actual accuracy (% correct) in this bucket */\n actualAccuracy: number;\n\n /** Number of predictions in this bucket */\n count: number;\n\n /** Calibration error |predicted - actual| */\n calibrationError: number;\n}\n\n// ============================================================================\n// Calibration Statistics\n// ============================================================================\n\nexport interface CalibrationStats {\n /** Reliability diagram buckets */\n buckets: CalibrationBucket[];\n\n /** Expected Calibration Error (weighted average of bucket errors) */\n expectedCalibrationError: number;\n\n /** Maximum Calibration Error (worst bucket) */\n maxCalibrationError: number;\n\n /** Brier Score (mean squared error of probabilistic predictions) */\n brierScore: number;\n\n /** Overall accuracy */\n overallAccuracy: number;\n\n /** Total predictions evaluated */\n totalPredictions: number;\n\n /** Stats by category */\n categoryStats: Map<string, CategoryCalibration>;\n\n /** Stats by framework */\n frameworkStats: Map<string, FrameworkCalibration>;\n\n /** When stats were last updated */\n lastUpdated: Date;\n}\n\nexport interface CategoryCalibration {\n category: RequirementCategory;\n totalPredictions: number;\n accuracy: number;\n expectedCalibrationError: number;\n adjustmentFactor: number;\n}\n\nexport interface FrameworkCalibration {\n framework: string;\n totalPredictions: number;\n accuracy: number;\n expectedCalibrationError: number;\n adjustmentFactor: number;\n}\n\n// ============================================================================\n// Calibration Model\n// ============================================================================\n\nexport interface CalibrationModel {\n /** Version of the model */\n version: string;\n\n /** When the model was trained */\n trainedAt: Date;\n\n /** Number of records used for training */\n trainingRecords: number;\n\n /** Global adjustment (default if no specific adjustment) */\n globalAdjustment: CalibrationAdjustment;\n\n /** Category-specific adjustments */\n categoryAdjustments: Map<string, CalibrationAdjustment>;\n\n /** Framework-specific adjustments */\n frameworkAdjustments: Map<string, CalibrationAdjustment>;\n\n /** Pattern-specific adjustments */\n patternAdjustments: Map<string, CalibrationAdjustment>;\n}\n\nexport interface CalibrationAdjustment {\n /** Scaling factor (multiply raw confidence) */\n scale: number;\n\n /** Offset (add after scaling) */\n offset: number;\n\n /** Confidence in this adjustment (based on sample size) */\n confidence: number;\n\n /** Number of samples used to calculate this adjustment */\n sampleSize: number;\n}\n\n// ============================================================================\n// Reliability Diagram Types\n// ============================================================================\n\nexport interface ReliabilityDiagram {\n /** The buckets for plotting */\n buckets: ReliabilityDiagramPoint[];\n\n /** Perfect calibration line (for reference) */\n perfectLine: [number, number][];\n\n /** Expected Calibration Error */\n ece: number;\n\n /** Area under reliability curve */\n auc: number;\n}\n\nexport interface ReliabilityDiagramPoint {\n /** Mean confidence in bucket */\n meanConfidence: number;\n\n /** Actual accuracy in bucket */\n actualAccuracy: number;\n\n /** Number of samples */\n count: number;\n\n /** Error bar (confidence interval) */\n errorBar?: [number, number];\n}\n\n// ============================================================================\n// Calibration Configuration\n// ============================================================================\n\nexport interface CalibrationConfig {\n /** Number of buckets for reliability diagram */\n numBuckets: number;\n\n /** Minimum samples needed for category adjustment */\n minCategorySamples: number;\n\n /** Minimum samples needed for framework adjustment */\n minFrameworkSamples: number;\n\n /** Minimum samples needed for pattern adjustment */\n minPatternSamples: number;\n\n /** Weight for recent records (exponential decay) */\n recencyWeight: number;\n\n /** How often to retrain the model (in records) */\n retrainThreshold: number;\n}\n\nexport const DEFAULT_CALIBRATION_CONFIG: CalibrationConfig = {\n numBuckets: 10,\n minCategorySamples: 20,\n minFrameworkSamples: 30,\n minPatternSamples: 50,\n recencyWeight: 0.95, // Recent records slightly more important\n retrainThreshold: 100, // Retrain after 100 new records\n};\n\n// ============================================================================\n// Time Series for Trends\n// ============================================================================\n\nexport interface CalibrationTimeSeries {\n /** Timestamp */\n timestamp: Date;\n\n /** ECE at this point */\n ece: number;\n\n /** Accuracy at this point */\n accuracy: number;\n\n /** Number of predictions evaluated */\n count: number;\n}\n","/**\n * Calibration Tracker\n *\n * Tracks predictions and their outcomes to enable calibration.\n * Provides in-memory storage with optional persistence.\n */\n\nimport type { VerificationStatus, RequirementCategory } from '../agents/types.js';\nimport type {\n CalibrationRecord,\n Prediction,\n PredictionContext,\n Outcome,\n CalibrationConfig,\n} from './types.js';\nimport { DEFAULT_CALIBRATION_CONFIG } from './types.js';\n\n/**\n * CalibrationTracker records predictions and outcomes for calibration analysis.\n */\nexport class CalibrationTracker {\n private records: Map<string, CalibrationRecord> = new Map();\n private pendingPredictions: Map<string, CalibrationRecord> = new Map();\n private config: CalibrationConfig;\n private recordsAddedSinceRetrain = 0;\n private onRetrainCallback?: () => Promise<void>;\n\n constructor(config: Partial<CalibrationConfig> = {}) {\n this.config = { ...DEFAULT_CALIBRATION_CONFIG, ...config };\n }\n\n // ==========================================================================\n // Prediction Recording\n // ==========================================================================\n\n /**\n * Record a new prediction (before outcome is known)\n */\n recordPrediction(\n predictionId: string,\n status: VerificationStatus,\n confidence: number,\n category: RequirementCategory,\n context: PredictionContext,\n options: {\n framework?: string;\n patternKey?: string;\n } = {}\n ): CalibrationRecord {\n const record: CalibrationRecord = {\n id: predictionId,\n predictionTimestamp: new Date(),\n prediction: {\n status,\n confidence,\n category,\n framework: options.framework,\n patternKey: options.patternKey,\n },\n context,\n calibrated: false,\n };\n\n this.pendingPredictions.set(predictionId, record);\n return record;\n }\n\n /**\n * Record multiple predictions at once\n */\n recordPredictions(\n predictions: Array<{\n id: string;\n status: VerificationStatus;\n confidence: number;\n category: RequirementCategory;\n context: PredictionContext;\n framework?: string;\n patternKey?: string;\n }>\n ): CalibrationRecord[] {\n return predictions.map((p) =>\n this.recordPrediction(p.id, p.status, p.confidence, p.category, p.context, {\n framework: p.framework,\n patternKey: p.patternKey,\n })\n );\n }\n\n // ==========================================================================\n // Outcome Recording\n // ==========================================================================\n\n /**\n * Record the actual outcome for a prediction\n */\n recordOutcome(\n predictionId: string,\n actualStatus: VerificationStatus,\n source: string,\n userFeedback?: string\n ): CalibrationRecord | null {\n // Find the prediction\n const record = this.pendingPredictions.get(predictionId);\n if (!record) {\n console.warn(`No pending prediction found for ID: ${predictionId}`);\n return null;\n }\n\n // Determine if prediction was correct\n const wasCorrect = record.prediction.status === actualStatus;\n\n // Update the record with outcome\n record.outcome = {\n status: actualStatus,\n wasCorrect,\n userFeedback,\n source,\n };\n record.outcomeTimestamp = new Date();\n\n // Move from pending to completed records\n this.pendingPredictions.delete(predictionId);\n this.records.set(predictionId, record);\n this.recordsAddedSinceRetrain++;\n\n // Check if we should trigger retrain\n if (\n this.onRetrainCallback &&\n this.recordsAddedSinceRetrain >= this.config.retrainThreshold\n ) {\n this.recordsAddedSinceRetrain = 0;\n this.onRetrainCallback().catch((err) => {\n console.warn('Calibration retrain failed:', err);\n });\n }\n\n return record;\n }\n\n /**\n * Record outcomes for multiple predictions\n */\n recordOutcomes(\n outcomes: Array<{\n predictionId: string;\n actualStatus: VerificationStatus;\n source: string;\n userFeedback?: string;\n }>\n ): CalibrationRecord[] {\n const results: CalibrationRecord[] = [];\n for (const outcome of outcomes) {\n const record = this.recordOutcome(\n outcome.predictionId,\n outcome.actualStatus,\n outcome.source,\n outcome.userFeedback\n );\n if (record) {\n results.push(record);\n }\n }\n return results;\n }\n\n /**\n * Bulk accept predictions as correct (common for \"accept all\")\n */\n acceptAllPredictions(predictionIds: string[], source: string): CalibrationRecord[] {\n const results: CalibrationRecord[] = [];\n for (const id of predictionIds) {\n const record = this.pendingPredictions.get(id);\n if (record) {\n const updated = this.recordOutcome(id, record.prediction.status, source);\n if (updated) {\n results.push(updated);\n }\n }\n }\n return results;\n }\n\n // ==========================================================================\n // Record Access\n // ==========================================================================\n\n /**\n * Get all completed records (with outcomes)\n */\n getCompletedRecords(): CalibrationRecord[] {\n return Array.from(this.records.values());\n }\n\n /**\n * Get records filtered by criteria\n */\n getFilteredRecords(filters: {\n category?: RequirementCategory;\n framework?: string;\n patternKey?: string;\n startDate?: Date;\n endDate?: Date;\n wasCorrect?: boolean;\n }): CalibrationRecord[] {\n return this.getCompletedRecords().filter((record) => {\n if (filters.category && record.prediction.category !== filters.category) {\n return false;\n }\n if (filters.framework && record.prediction.framework !== filters.framework) {\n return false;\n }\n if (filters.patternKey && record.prediction.patternKey !== filters.patternKey) {\n return false;\n }\n if (filters.startDate && record.predictionTimestamp < filters.startDate) {\n return false;\n }\n if (filters.endDate && record.predictionTimestamp > filters.endDate) {\n return false;\n }\n if (\n filters.wasCorrect !== undefined &&\n record.outcome?.wasCorrect !== filters.wasCorrect\n ) {\n return false;\n }\n return true;\n });\n }\n\n /**\n * Get pending predictions (awaiting outcomes)\n */\n getPendingPredictions(): CalibrationRecord[] {\n return Array.from(this.pendingPredictions.values());\n }\n\n /**\n * Get a specific record\n */\n getRecord(id: string): CalibrationRecord | undefined {\n return this.records.get(id) || this.pendingPredictions.get(id);\n }\n\n // ==========================================================================\n // Statistics\n // ==========================================================================\n\n /**\n * Get basic statistics about tracked predictions\n */\n getStats(): {\n totalCompleted: number;\n totalPending: number;\n correctPredictions: number;\n incorrectPredictions: number;\n overallAccuracy: number;\n byCategory: Map<string, { total: number; correct: number; accuracy: number }>;\n byFramework: Map<string, { total: number; correct: number; accuracy: number }>;\n } {\n const completed = this.getCompletedRecords();\n const correct = completed.filter((r) => r.outcome?.wasCorrect).length;\n const incorrect = completed.length - correct;\n\n // By category\n const byCategory = new Map<string, { total: number; correct: number; accuracy: number }>();\n for (const record of completed) {\n const cat = record.prediction.category;\n const current = byCategory.get(cat) || { total: 0, correct: 0, accuracy: 0 };\n current.total++;\n if (record.outcome?.wasCorrect) current.correct++;\n current.accuracy = current.total > 0 ? current.correct / current.total : 0;\n byCategory.set(cat, current);\n }\n\n // By framework\n const byFramework = new Map<string, { total: number; correct: number; accuracy: number }>();\n for (const record of completed) {\n const fw = record.prediction.framework || 'unknown';\n const current = byFramework.get(fw) || { total: 0, correct: 0, accuracy: 0 };\n current.total++;\n if (record.outcome?.wasCorrect) current.correct++;\n current.accuracy = current.total > 0 ? current.correct / current.total : 0;\n byFramework.set(fw, current);\n }\n\n return {\n totalCompleted: completed.length,\n totalPending: this.pendingPredictions.size,\n correctPredictions: correct,\n incorrectPredictions: incorrect,\n overallAccuracy: completed.length > 0 ? correct / completed.length : 0,\n byCategory,\n byFramework,\n };\n }\n\n // ==========================================================================\n // Callbacks\n // ==========================================================================\n\n /**\n * Set callback for when retrain threshold is reached\n */\n onRetrain(callback: () => Promise<void>): void {\n this.onRetrainCallback = callback;\n }\n\n // ==========================================================================\n // Persistence\n // ==========================================================================\n\n /**\n * Export all records for persistence\n */\n exportRecords(): {\n completed: CalibrationRecord[];\n pending: CalibrationRecord[];\n exportedAt: Date;\n } {\n return {\n completed: this.getCompletedRecords(),\n pending: this.getPendingPredictions(),\n exportedAt: new Date(),\n };\n }\n\n /**\n * Import records from storage\n */\n importRecords(data: {\n completed: CalibrationRecord[];\n pending: CalibrationRecord[];\n }): void {\n // Clear existing records\n this.records.clear();\n this.pendingPredictions.clear();\n\n // Import completed records\n for (const record of data.completed) {\n this.records.set(record.id, record);\n }\n\n // Import pending records\n for (const record of data.pending) {\n this.pendingPredictions.set(record.id, record);\n }\n }\n\n /**\n * Clear all records\n */\n clear(): void {\n this.records.clear();\n this.pendingPredictions.clear();\n this.recordsAddedSinceRetrain = 0;\n }\n\n /**\n * Mark records as calibrated\n */\n markCalibrated(ids: string[]): void {\n for (const id of ids) {\n const record = this.records.get(id);\n if (record) {\n record.calibrated = true;\n }\n }\n }\n\n /**\n * Get uncalibrated records (for training)\n */\n getUncalibratedRecords(): CalibrationRecord[] {\n return this.getCompletedRecords().filter((r) => !r.calibrated);\n }\n}\n\n// Singleton instance\nlet calibrationTrackerInstance: CalibrationTracker | null = null;\n\n/**\n * Get the singleton CalibrationTracker instance\n */\nexport function getCalibrationTracker(\n config?: Partial<CalibrationConfig>\n): CalibrationTracker {\n if (!calibrationTrackerInstance) {\n calibrationTrackerInstance = new CalibrationTracker(config);\n }\n return calibrationTrackerInstance;\n}\n\n/**\n * Reset the singleton instance\n */\nexport function resetCalibrationTracker(): void {\n calibrationTrackerInstance = null;\n}\n","/**\n * Confidence Calibrator\n *\n * Calibrates confidence scores based on historical accuracy.\n * Implements reliability diagrams, ECE/MCE/Brier calculations,\n * and Platt scaling for confidence adjustment.\n */\n\nimport { CalibrationTracker } from './calibration-tracker.js';\nimport {\n DEFAULT_CALIBRATION_CONFIG,\n type CalibrationConfig,\n type CalibrationRecord,\n type CalibrationStats,\n type CalibrationBucket,\n type CalibrationModel,\n type CalibrationAdjustment,\n type CategoryCalibration,\n type FrameworkCalibration,\n type ReliabilityDiagram,\n type ReliabilityDiagramPoint,\n} from './types.js';\nimport type { RequirementCategory } from '../agents/types.js';\n\n/**\n * ConfidenceCalibrator analyzes prediction accuracy and adjusts\n * confidence scores to improve calibration.\n */\nexport class ConfidenceCalibrator {\n private tracker: CalibrationTracker;\n private config: CalibrationConfig;\n private model: CalibrationModel | null = null;\n\n constructor(\n tracker: CalibrationTracker,\n config: Partial<CalibrationConfig> = {}\n ) {\n this.tracker = tracker;\n this.config = { ...DEFAULT_CALIBRATION_CONFIG, ...config };\n\n // Set up automatic retraining\n this.tracker.onRetrain(async () => {\n await this.retrain();\n });\n }\n\n // ==========================================================================\n // Calibration Metrics\n // ==========================================================================\n\n /**\n * Calculate full calibration statistics\n */\n calculateStats(): CalibrationStats {\n const records = this.tracker.getCompletedRecords();\n const buckets = this.createBuckets(records);\n\n // Calculate ECE (Expected Calibration Error)\n const ece = this.calculateECE(buckets, records.length);\n\n // Calculate MCE (Maximum Calibration Error)\n const mce = this.calculateMCE(buckets);\n\n // Calculate Brier Score\n const brier = this.calculateBrierScore(records);\n\n // Overall accuracy\n const correct = records.filter((r) => r.outcome?.wasCorrect).length;\n const overallAccuracy = records.length > 0 ? correct / records.length : 0;\n\n // Category stats\n const categoryStats = this.calculateCategoryStats(records);\n\n // Framework stats\n const frameworkStats = this.calculateFrameworkStats(records);\n\n return {\n buckets,\n expectedCalibrationError: ece,\n maxCalibrationError: mce,\n brierScore: brier,\n overallAccuracy,\n totalPredictions: records.length,\n categoryStats,\n frameworkStats,\n lastUpdated: new Date(),\n };\n }\n\n /**\n * Create calibration buckets from records\n */\n private createBuckets(records: CalibrationRecord[]): CalibrationBucket[] {\n const bucketSize = 100 / this.config.numBuckets;\n const buckets: CalibrationBucket[] = [];\n\n for (let i = 0; i < this.config.numBuckets; i++) {\n const min = i * bucketSize;\n const max = (i + 1) * bucketSize;\n\n // Get records in this bucket\n const bucketRecords = records.filter((r) => {\n const conf = r.prediction.confidence;\n return conf >= min && conf < max;\n });\n\n if (bucketRecords.length === 0) {\n buckets.push({\n confidenceRange: [min, max],\n predictedAccuracy: (min + max) / 2 / 100,\n actualAccuracy: 0,\n count: 0,\n calibrationError: 0,\n });\n continue;\n }\n\n // Calculate predicted accuracy (average confidence)\n const predictedAccuracy =\n bucketRecords.reduce((sum, r) => sum + r.prediction.confidence, 0) /\n bucketRecords.length /\n 100;\n\n // Calculate actual accuracy\n const correct = bucketRecords.filter((r) => r.outcome?.wasCorrect).length;\n const actualAccuracy = correct / bucketRecords.length;\n\n // Calibration error\n const calibrationError = Math.abs(predictedAccuracy - actualAccuracy);\n\n buckets.push({\n confidenceRange: [min, max],\n predictedAccuracy,\n actualAccuracy,\n count: bucketRecords.length,\n calibrationError,\n });\n }\n\n return buckets;\n }\n\n /**\n * Calculate Expected Calibration Error (ECE)\n * Weighted average of bucket calibration errors\n */\n private calculateECE(buckets: CalibrationBucket[], totalRecords: number): number {\n if (totalRecords === 0) return 0;\n\n let ece = 0;\n for (const bucket of buckets) {\n const weight = bucket.count / totalRecords;\n ece += weight * bucket.calibrationError;\n }\n\n return ece;\n }\n\n /**\n * Calculate Maximum Calibration Error (MCE)\n * Worst bucket calibration error\n */\n private calculateMCE(buckets: CalibrationBucket[]): number {\n if (buckets.length === 0) return 0;\n\n return Math.max(...buckets.filter((b) => b.count > 0).map((b) => b.calibrationError));\n }\n\n /**\n * Calculate Brier Score\n * Mean squared error of probabilistic predictions\n */\n private calculateBrierScore(records: CalibrationRecord[]): number {\n if (records.length === 0) return 0;\n\n let sumSquaredError = 0;\n for (const record of records) {\n const predicted = record.prediction.confidence / 100;\n const actual = record.outcome?.wasCorrect ? 1 : 0;\n sumSquaredError += Math.pow(predicted - actual, 2);\n }\n\n return sumSquaredError / records.length;\n }\n\n /**\n * Calculate category-specific calibration stats\n */\n private calculateCategoryStats(\n records: CalibrationRecord[]\n ): Map<string, CategoryCalibration> {\n const stats = new Map<string, CategoryCalibration>();\n\n // Group by category\n const byCategory = new Map<string, CalibrationRecord[]>();\n for (const record of records) {\n const cat = record.prediction.category;\n if (!byCategory.has(cat)) {\n byCategory.set(cat, []);\n }\n byCategory.get(cat)!.push(record);\n }\n\n // Calculate stats for each category\n for (const [category, catRecords] of byCategory) {\n const buckets = this.createBuckets(catRecords);\n const ece = this.calculateECE(buckets, catRecords.length);\n const correct = catRecords.filter((r) => r.outcome?.wasCorrect).length;\n const accuracy = catRecords.length > 0 ? correct / catRecords.length : 0;\n\n // Calculate adjustment factor\n const adjustmentFactor = this.calculateAdjustmentFactor(catRecords);\n\n stats.set(category, {\n category: category as RequirementCategory,\n totalPredictions: catRecords.length,\n accuracy,\n expectedCalibrationError: ece,\n adjustmentFactor,\n });\n }\n\n return stats;\n }\n\n /**\n * Calculate framework-specific calibration stats\n */\n private calculateFrameworkStats(\n records: CalibrationRecord[]\n ): Map<string, FrameworkCalibration> {\n const stats = new Map<string, FrameworkCalibration>();\n\n // Group by framework\n const byFramework = new Map<string, CalibrationRecord[]>();\n for (const record of records) {\n const fw = record.prediction.framework || 'unknown';\n if (!byFramework.has(fw)) {\n byFramework.set(fw, []);\n }\n byFramework.get(fw)!.push(record);\n }\n\n // Calculate stats for each framework\n for (const [framework, fwRecords] of byFramework) {\n const buckets = this.createBuckets(fwRecords);\n const ece = this.calculateECE(buckets, fwRecords.length);\n const correct = fwRecords.filter((r) => r.outcome?.wasCorrect).length;\n const accuracy = fwRecords.length > 0 ? correct / fwRecords.length : 0;\n\n // Calculate adjustment factor\n const adjustmentFactor = this.calculateAdjustmentFactor(fwRecords);\n\n stats.set(framework, {\n framework,\n totalPredictions: fwRecords.length,\n accuracy,\n expectedCalibrationError: ece,\n adjustmentFactor,\n });\n }\n\n return stats;\n }\n\n /**\n * Calculate adjustment factor using simple linear regression\n */\n private calculateAdjustmentFactor(records: CalibrationRecord[]): number {\n if (records.length < 5) return 1.0; // Not enough data\n\n // Calculate mean predicted and actual\n const meanPredicted =\n records.reduce((sum, r) => sum + r.prediction.confidence, 0) / records.length / 100;\n const meanActual =\n records.filter((r) => r.outcome?.wasCorrect).length / records.length;\n\n // If predictions are too optimistic, reduce; if pessimistic, increase\n if (meanPredicted === 0) return 1.0;\n return meanActual / meanPredicted;\n }\n\n // ==========================================================================\n // Reliability Diagram\n // ==========================================================================\n\n /**\n * Generate reliability diagram data\n */\n generateReliabilityDiagram(): ReliabilityDiagram {\n const records = this.tracker.getCompletedRecords();\n const buckets = this.createBuckets(records);\n\n // Create diagram points\n const points: ReliabilityDiagramPoint[] = buckets\n .filter((b) => b.count > 0)\n .map((bucket) => ({\n meanConfidence: bucket.predictedAccuracy,\n actualAccuracy: bucket.actualAccuracy,\n count: bucket.count,\n errorBar: this.calculateConfidenceInterval(bucket.actualAccuracy, bucket.count),\n }));\n\n // Perfect calibration line\n const perfectLine: [number, number][] = [\n [0, 0],\n [1, 1],\n ];\n\n // Calculate ECE\n const ece = this.calculateECE(buckets, records.length);\n\n // Calculate AUC (area under reliability curve) - approximate with trapezoid rule\n let auc = 0;\n for (let i = 1; i < points.length; i++) {\n const width = points[i].meanConfidence - points[i - 1].meanConfidence;\n const avgHeight = (points[i].actualAccuracy + points[i - 1].actualAccuracy) / 2;\n auc += width * avgHeight;\n }\n\n return { buckets: points, perfectLine, ece, auc };\n }\n\n /**\n * Calculate confidence interval for proportion\n */\n private calculateConfidenceInterval(\n proportion: number,\n n: number\n ): [number, number] {\n if (n === 0) return [0, 0];\n\n // Wilson score interval (z=1.96 for 95% CI)\n const z = 1.96;\n const denominator = 1 + (z * z) / n;\n const center = (proportion + (z * z) / (2 * n)) / denominator;\n const margin =\n (z * Math.sqrt((proportion * (1 - proportion) + (z * z) / (4 * n)) / n)) / denominator;\n\n return [Math.max(0, center - margin), Math.min(1, center + margin)];\n }\n\n // ==========================================================================\n // Calibration Model Training\n // ==========================================================================\n\n /**\n * Train/retrain the calibration model\n */\n async retrain(): Promise<CalibrationModel> {\n const records = this.tracker.getCompletedRecords();\n\n // Calculate global adjustment\n const globalAdjustment = this.trainAdjustment(records);\n\n // Calculate category adjustments\n const categoryAdjustments = new Map<string, CalibrationAdjustment>();\n const stats = this.calculateCategoryStats(records);\n for (const [category, catStats] of stats) {\n if (catStats.totalPredictions >= this.config.minCategorySamples) {\n const catRecords = records.filter((r) => r.prediction.category === category);\n categoryAdjustments.set(category, this.trainAdjustment(catRecords));\n }\n }\n\n // Calculate framework adjustments\n const frameworkAdjustments = new Map<string, CalibrationAdjustment>();\n const fwStats = this.calculateFrameworkStats(records);\n for (const [framework, fwStat] of fwStats) {\n if (fwStat.totalPredictions >= this.config.minFrameworkSamples) {\n const fwRecords = records.filter((r) => r.prediction.framework === framework);\n frameworkAdjustments.set(framework, this.trainAdjustment(fwRecords));\n }\n }\n\n // Calculate pattern adjustments\n const patternAdjustments = new Map<string, CalibrationAdjustment>();\n const byPattern = new Map<string, CalibrationRecord[]>();\n for (const record of records) {\n const pattern = record.prediction.patternKey;\n if (pattern) {\n if (!byPattern.has(pattern)) {\n byPattern.set(pattern, []);\n }\n byPattern.get(pattern)!.push(record);\n }\n }\n for (const [pattern, patternRecords] of byPattern) {\n if (patternRecords.length >= this.config.minPatternSamples) {\n patternAdjustments.set(pattern, this.trainAdjustment(patternRecords));\n }\n }\n\n this.model = {\n version: `1.0.${Date.now()}`,\n trainedAt: new Date(),\n trainingRecords: records.length,\n globalAdjustment,\n categoryAdjustments,\n frameworkAdjustments,\n patternAdjustments,\n };\n\n // Mark records as calibrated\n this.tracker.markCalibrated(records.map((r) => r.id));\n\n return this.model;\n }\n\n /**\n * Train adjustment using Platt scaling (simplified)\n */\n private trainAdjustment(records: CalibrationRecord[]): CalibrationAdjustment {\n if (records.length < 5) {\n return { scale: 1.0, offset: 0, confidence: 0, sampleSize: records.length };\n }\n\n // Simple linear regression: actual = scale * predicted + offset\n const n = records.length;\n let sumX = 0,\n sumY = 0,\n sumXY = 0,\n sumX2 = 0;\n\n for (const record of records) {\n const x = record.prediction.confidence / 100;\n const y = record.outcome?.wasCorrect ? 1 : 0;\n sumX += x;\n sumY += y;\n sumXY += x * y;\n sumX2 += x * x;\n }\n\n const denom = n * sumX2 - sumX * sumX;\n let scale = 1.0;\n let offset = 0;\n\n if (Math.abs(denom) > 0.0001) {\n scale = (n * sumXY - sumX * sumY) / denom;\n offset = (sumY - scale * sumX) / n;\n }\n\n // Constrain scale to reasonable bounds\n scale = Math.max(0.5, Math.min(2.0, scale));\n offset = Math.max(-0.3, Math.min(0.3, offset));\n\n // Calculate confidence based on sample size\n const adjustmentConfidence = Math.min(1, n / 100);\n\n return {\n scale,\n offset,\n confidence: adjustmentConfidence,\n sampleSize: n,\n };\n }\n\n // ==========================================================================\n // Confidence Calibration\n // ==========================================================================\n\n /**\n * Calibrate a raw confidence score\n */\n calibrate(\n rawConfidence: number,\n category?: RequirementCategory,\n framework?: string,\n patternKey?: string\n ): number {\n if (!this.model) {\n return rawConfidence; // No model trained yet\n }\n\n // Get the most specific adjustment available\n let adjustment = this.model.globalAdjustment;\n\n // Check for pattern-specific adjustment (most specific)\n if (patternKey && this.model.patternAdjustments.has(patternKey)) {\n adjustment = this.model.patternAdjustments.get(patternKey)!;\n }\n // Check for framework-specific adjustment\n else if (framework && this.model.frameworkAdjustments.has(framework)) {\n adjustment = this.model.frameworkAdjustments.get(framework)!;\n }\n // Check for category-specific adjustment\n else if (category && this.model.categoryAdjustments.has(category)) {\n adjustment = this.model.categoryAdjustments.get(category)!;\n }\n\n // Apply calibration\n const calibrated = this.applyCalibration(rawConfidence, adjustment);\n\n return Math.max(0, Math.min(100, Math.round(calibrated)));\n }\n\n /**\n * Apply calibration adjustment to raw confidence\n */\n private applyCalibration(\n rawConfidence: number,\n adjustment: CalibrationAdjustment\n ): number {\n const raw = rawConfidence / 100;\n\n // Weighted average of raw and adjusted\n // Weight by adjustment confidence\n const adjusted = adjustment.scale * raw + adjustment.offset;\n const calibrated = adjustment.confidence * adjusted + (1 - adjustment.confidence) * raw;\n\n return calibrated * 100;\n }\n\n // ==========================================================================\n // Model Access\n // ==========================================================================\n\n /**\n * Get the current calibration model\n */\n getModel(): CalibrationModel | null {\n return this.model;\n }\n\n /**\n * Import a previously trained model\n */\n importModel(model: CalibrationModel): void {\n this.model = model;\n }\n\n /**\n * Export the model for persistence\n */\n exportModel(): CalibrationModel | null {\n return this.model;\n }\n\n /**\n * Check if model is trained\n */\n isModelTrained(): boolean {\n return this.model !== null;\n }\n\n /**\n * Get calibration recommendations\n */\n getRecommendations(): string[] {\n const recommendations: string[] = [];\n const stats = this.calculateStats();\n\n if (stats.expectedCalibrationError > 0.15) {\n recommendations.push(\n `High calibration error (${(stats.expectedCalibrationError * 100).toFixed(1)}%). ` +\n 'Collect more feedback to improve accuracy.'\n );\n }\n\n if (stats.totalPredictions < 50) {\n recommendations.push(\n 'Limited calibration data. Need more predictions with outcomes to improve accuracy.'\n );\n }\n\n // Check for categories with poor calibration\n for (const [category, catStats] of stats.categoryStats) {\n if (catStats.expectedCalibrationError > 0.2 && catStats.totalPredictions >= 10) {\n recommendations.push(\n `Category \"${category}\" has high calibration error. Consider category-specific rules.`\n );\n }\n }\n\n return recommendations;\n }\n}\n\n// Singleton instance\nlet confidenceCalibratorInstance: ConfidenceCalibrator | null = null;\n\n/**\n * Get the singleton ConfidenceCalibrator instance\n */\nexport function getConfidenceCalibrator(\n tracker?: CalibrationTracker,\n config?: Partial<CalibrationConfig>\n): ConfidenceCalibrator {\n if (!confidenceCalibratorInstance && tracker) {\n confidenceCalibratorInstance = new ConfidenceCalibrator(tracker, config);\n }\n if (!confidenceCalibratorInstance) {\n throw new Error('ConfidenceCalibrator not initialized. Provide tracker.');\n }\n return confidenceCalibratorInstance;\n}\n\n/**\n * Reset the singleton instance\n */\nexport function resetConfidenceCalibrator(): void {\n confidenceCalibratorInstance = null;\n}\n","/**\n * Confidence Calibration Module\n *\n * Tracks predictions and outcomes to calibrate confidence scores\n * based on historical accuracy. Improves prediction reliability\n * over time through feedback learning.\n *\n * Key Features:\n * - Prediction tracking and outcome recording\n * - Expected Calibration Error (ECE) calculation\n * - Maximum Calibration Error (MCE) calculation\n * - Brier Score calculation\n * - Reliability diagram generation\n * - Automatic confidence adjustment\n */\n\n// Types\nexport type {\n Prediction,\n PredictionContext,\n Outcome,\n CalibrationRecord,\n CalibrationBucket,\n CalibrationStats,\n CalibrationModel,\n CalibrationAdjustment,\n CategoryCalibration,\n FrameworkCalibration,\n ReliabilityDiagram,\n ReliabilityDiagramPoint,\n CalibrationConfig,\n CalibrationTimeSeries,\n} from './types.js';\n\nexport { DEFAULT_CALIBRATION_CONFIG } from './types.js';\n\n// Calibration Tracker\nexport {\n CalibrationTracker,\n getCalibrationTracker,\n resetCalibrationTracker,\n} from './calibration-tracker.js';\n\n// Confidence Calibrator\nexport {\n ConfidenceCalibrator,\n getConfidenceCalibrator,\n resetConfidenceCalibrator,\n} from './confidence-calibrator.js';\n\n// ==========================================================================\n// Convenience Functions\n// ==========================================================================\n\nimport { CalibrationTracker } from './calibration-tracker.js';\nimport { ConfidenceCalibrator } from './confidence-calibrator.js';\nimport type { CalibrationConfig, CalibrationStats, ReliabilityDiagram } from './types.js';\nimport type { VerificationStatus, RequirementCategory } from '../agents/types.js';\n\n/**\n * Initialize the calibration system\n */\nexport function initializeCalibrationSystem(\n config?: Partial<CalibrationConfig>\n): {\n tracker: CalibrationTracker;\n calibrator: ConfidenceCalibrator;\n} {\n const tracker = new CalibrationTracker(config);\n const calibrator = new ConfidenceCalibrator(tracker, config);\n\n return { tracker, calibrator };\n}\n\n/**\n * Quick calibration check for a single confidence score\n */\nexport function quickCalibrate(\n rawConfidence: number,\n calibrator: ConfidenceCalibrator,\n options?: {\n category?: RequirementCategory;\n framework?: string;\n patternKey?: string;\n }\n): number {\n if (!calibrator.isModelTrained()) {\n return rawConfidence;\n }\n\n return calibrator.calibrate(\n rawConfidence,\n options?.category,\n options?.framework,\n options?.patternKey\n );\n}\n\n/**\n * Get a summary of calibration health\n */\nexport function getCalibrationHealth(stats: CalibrationStats): {\n status: 'excellent' | 'good' | 'fair' | 'poor';\n ece: number;\n accuracy: number;\n dataPoints: number;\n recommendation: string;\n} {\n const ece = stats.expectedCalibrationError;\n const accuracy = stats.overallAccuracy;\n const dataPoints = stats.totalPredictions;\n\n let status: 'excellent' | 'good' | 'fair' | 'poor';\n let recommendation: string;\n\n if (dataPoints < 20) {\n status = 'poor';\n recommendation = 'Insufficient data. Continue collecting feedback to improve calibration.';\n } else if (ece <= 0.05 && accuracy >= 0.85) {\n status = 'excellent';\n recommendation = 'Calibration is excellent. Continue monitoring for drift.';\n } else if (ece <= 0.10 && accuracy >= 0.75) {\n status = 'good';\n recommendation = 'Calibration is good. Minor improvements possible with more data.';\n } else if (ece <= 0.15 && accuracy >= 0.65) {\n status = 'fair';\n recommendation = 'Calibration needs improvement. Focus on categories with high error.';\n } else {\n status = 'poor';\n recommendation = 'Calibration is poor. Consider reviewing verification logic or collecting more diverse feedback.';\n }\n\n return {\n status,\n ece: Math.round(ece * 100) / 100,\n accuracy: Math.round(accuracy * 100) / 100,\n dataPoints,\n recommendation,\n };\n}\n\n/**\n * Format reliability diagram for display\n */\nexport function formatReliabilityDiagram(diagram: ReliabilityDiagram): string {\n const lines: string[] = [];\n lines.push('Reliability Diagram');\n lines.push('==================');\n lines.push('');\n lines.push('Confidence | Accuracy | Count');\n lines.push('-----------|----------|------');\n\n for (const point of diagram.buckets) {\n const conf = (point.meanConfidence * 100).toFixed(0).padStart(9);\n const acc = (point.actualAccuracy * 100).toFixed(0).padStart(7);\n const count = point.count.toString().padStart(5);\n lines.push(`${conf}% | ${acc}% | ${count}`);\n }\n\n lines.push('');\n lines.push(`ECE: ${(diagram.ece * 100).toFixed(1)}%`);\n\n return lines.join('\\n');\n}\n","/**\n * Validator Agent\n *\n * Responsible for:\n * - Cross-validating requirements against implementations\n * - Determining verification status (verified, drift, undocumented, unimplemented)\n * - Debating findings when confidence is low\n * - Scoring confidence levels\n * - Flagging disputes for human review\n */\n\nimport { createJsonCompletion, createCompletion } from '../ai/client.js';\nimport { BaseAgent } from './base-agent.js';\nimport {\n TaskMessage,\n ResultMessage,\n Requirement,\n RequirementMapping,\n VerifiedRequirement,\n VerificationStatus,\n DriftSeverity,\n DebateRecord,\n DebateRound,\n ValidationResult,\n VerificationSummary,\n RuleValidationResult,\n} from './types.js';\nimport {\n getPatternMatcher,\n getPatternCollector,\n FrameworkContext,\n anonymizeAnalysisReport,\n extractDriftType,\n} from '../knowledge-base/index.js';\nimport {\n getRulesRegistry,\n RulesRegistry,\n RuleResult,\n RuleTarget,\n} from '../marketplace/index.js';\nimport {\n GitHistoryAnalyzer,\n DocFreshnessAnalyzer,\n CodeDocSyncDetector,\n initializeGitAnalysis,\n type FreshnessResult,\n type DesyncResult,\n type DriftRiskScore,\n} from '../git-analysis/index.js';\nimport type { GitAnalysisSummary, DocFreshnessInfo } from './types.js';\nimport {\n CalibrationTracker,\n ConfidenceCalibrator,\n getCalibrationTracker,\n getConfidenceCalibrator,\n type CalibrationStats,\n type PredictionContext,\n} from '../calibration/index.js';\n\n// ============================================================================\n// Validator Agent\n// ============================================================================\n\nexport class ValidatorAgent extends BaseAgent {\n private confidenceThreshold = 70; // Below this, trigger debate\n private maxDebateRounds = 3;\n private frameworkContext: FrameworkContext | null = null;\n private rulesRegistry: RulesRegistry;\n\n // Git analysis components\n private gitAnalyzer: GitHistoryAnalyzer | null = null;\n private freshnessAnalyzer: DocFreshnessAnalyzer | null = null;\n private syncDetector: CodeDocSyncDetector | null = null;\n private repoPath: string | null = null;\n\n // Calibration components\n private calibrationTracker: CalibrationTracker;\n private confidenceCalibrator: ConfidenceCalibrator;\n private enableCalibration = true;\n\n constructor() {\n super('validator');\n this.rulesRegistry = getRulesRegistry();\n this.calibrationTracker = getCalibrationTracker();\n this.confidenceCalibrator = getConfidenceCalibrator(this.calibrationTracker);\n }\n\n /**\n * Enable or disable confidence calibration\n */\n setCalibrationEnabled(enabled: boolean): void {\n this.enableCalibration = enabled;\n }\n\n /**\n * Get calibration statistics\n */\n getCalibrationStats(): CalibrationStats {\n return this.confidenceCalibrator.calculateStats();\n }\n\n /**\n * Record user feedback for calibration\n */\n recordFeedback(\n predictionId: string,\n actualStatus: VerificationStatus,\n userFeedback?: string\n ): void {\n this.calibrationTracker.recordOutcome(\n predictionId,\n actualStatus,\n 'user',\n userFeedback\n );\n }\n\n /**\n * Accept all predictions as correct (bulk feedback)\n */\n acceptAllPredictions(predictionIds: string[]): void {\n this.calibrationTracker.acceptAllPredictions(predictionIds, 'user');\n }\n\n /**\n * Retrain calibration model with current data\n */\n async retrainCalibration(): Promise<void> {\n await this.confidenceCalibrator.retrain();\n this.emitEvent('validator:calibration_retrained', {\n modelVersion: this.confidenceCalibrator.getModel()?.version,\n });\n }\n\n /**\n * Initialize git analysis for the repository\n */\n initializeGitAnalysis(repoPath: string): void {\n try {\n this.repoPath = repoPath;\n const { gitAnalyzer, freshnessAnalyzer, syncDetector } = initializeGitAnalysis(repoPath);\n this.gitAnalyzer = gitAnalyzer;\n this.freshnessAnalyzer = freshnessAnalyzer;\n this.syncDetector = syncDetector;\n this.emitEvent('validator:git_initialized', { repoPath });\n } catch (err) {\n console.warn('Failed to initialize git analysis:', err);\n this.gitAnalyzer = null;\n this.freshnessAnalyzer = null;\n this.syncDetector = null;\n }\n }\n\n /**\n * Check if git analysis is available\n */\n hasGitAnalysis(): boolean {\n return this.gitAnalyzer !== null;\n }\n\n /**\n * Set framework context for pattern-enhanced validation\n */\n setFrameworkContext(frameworks: string[], languages: string[]): void {\n const matcher = getPatternMatcher();\n this.frameworkContext = matcher.buildFrameworkContext(frameworks, languages);\n this.emitEvent('validator:context_set', {\n frameworks,\n languages,\n patternsLoaded: this.frameworkContext.patterns.length,\n });\n }\n\n async execute(task: TaskMessage): Promise<ResultMessage> {\n const startTime = Date.now();\n this.status = 'executing';\n this.emitEvent('agent:task_started', { taskId: task.payload.taskId });\n\n try {\n const { taskType, inputs } = task.payload;\n let result: unknown;\n let totalTokens = { input: 0, output: 0 };\n\n switch (taskType) {\n case 'validate': {\n const validation = await this.validate(\n inputs.docRequirements as Requirement[],\n inputs.codeFeatures as Requirement[],\n inputs.mappings as RequirementMapping[],\n inputs.docsContent as string,\n inputs.codeContent as string,\n inputs.enableDebate as boolean\n );\n result = validation;\n totalTokens = validation.tokensUsed;\n break;\n }\n case 'debate': {\n const debated = await this.debateFinding(\n inputs.finding as VerifiedRequirement,\n inputs.docsContent as string,\n inputs.codeContent as string\n );\n result = debated;\n totalTokens = debated.tokensUsed;\n break;\n }\n case 'score_confidence': {\n const scored = await this.scoreConfidence(\n inputs.findings as VerifiedRequirement[]\n );\n result = scored;\n break;\n }\n default:\n throw new Error(`Unknown task type: ${taskType}`);\n }\n\n const executionTime = Date.now() - startTime;\n this.addTokens(totalTokens.input, totalTokens.output);\n this.tasksCompleted++;\n this.status = 'complete';\n this.emitEvent('agent:task_completed', { taskId: task.payload.taskId, success: true });\n\n const confidence = this.calculateOverallConfidence(result);\n\n return this.createSuccessResult(\n task.payload.taskId,\n result,\n confidence,\n totalTokens,\n executionTime\n );\n } catch (err) {\n const executionTime = Date.now() - startTime;\n const error = err instanceof Error ? err.message : 'Unknown error';\n this.status = 'error';\n\n return this.createErrorResult(task.payload.taskId, error, executionTime);\n }\n }\n\n /**\n * Main validation: cross-validate requirements against code\n */\n async validate(\n docRequirements: Requirement[],\n codeFeatures: Requirement[],\n mappings: RequirementMapping[],\n docsContent: string,\n codeContent: string,\n enableDebate = true\n ): Promise<ValidationResult & { tokensUsed: { input: number; output: number } }> {\n // Step 1: Initial cross-validation\n const { verified, tokensUsed } = await this.crossValidate(\n docRequirements,\n codeFeatures,\n mappings,\n docsContent,\n codeContent\n );\n\n // Step 2: Identify low-confidence findings for debate\n const lowConfidence = verified.filter(\n (v) => v.confidence < this.confidenceThreshold && enableDebate\n );\n\n let debateTokens = { input: 0, output: 0 };\n let debatesTriggered = 0;\n let debatesOverturned = 0;\n\n // Step 3: Debate low-confidence findings\n if (lowConfidence.length > 0 && enableDebate) {\n this.emitEvent('agent:debate_started', {\n count: lowConfidence.length,\n findings: lowConfidence.map((f) => f.requirement.id),\n });\n\n for (const finding of lowConfidence) {\n debatesTriggered++;\n const debated = await this.debateFinding(finding, docsContent, codeContent);\n debateTokens.input += debated.tokensUsed.input;\n debateTokens.output += debated.tokensUsed.output;\n\n // Update the finding with debate results\n const idx = verified.findIndex((v) => v.requirement.id === finding.requirement.id);\n if (idx !== -1) {\n verified[idx] = debated.finding;\n if (debated.finding.debate?.outcome === 'overturned') {\n debatesOverturned++;\n }\n }\n }\n\n this.emitEvent('agent:debate_resolved', {\n triggered: debatesTriggered,\n overturned: debatesOverturned,\n });\n }\n\n // Step 4: Identify disputes (still low confidence after debate)\n const disputes = verified.filter(\n (v) => v.confidence < this.confidenceThreshold || v.status === 'disputed'\n );\n\n // Step 5: Execute community rules\n const ruleResults = this.executeCommunityRules(docsContent, codeContent);\n this.emitEvent('validator:rules_executed', {\n total: ruleResults.results.length,\n passed: ruleResults.passed,\n failed: ruleResults.failed,\n });\n\n // Step 6: Build summary\n const summary: VerificationSummary = {\n total: verified.length,\n verified: verified.filter((v) => v.status === 'verified').length,\n drift: verified.filter((v) => v.status === 'drift').length,\n undocumented: verified.filter((v) => v.status === 'undocumented').length,\n unimplemented: verified.filter((v) => v.status === 'unimplemented').length,\n disputed: disputes.length,\n overallConfidence: Math.round(\n verified.reduce((sum, v) => sum + v.confidence, 0) / Math.max(verified.length, 1)\n ),\n debatesTriggered,\n debatesOverturned,\n rulesExecuted: ruleResults.results.length,\n rulesPassed: ruleResults.passed,\n };\n\n const validationResult = {\n verified,\n summary,\n disputes,\n ruleResults,\n tokensUsed: {\n input: tokensUsed.input + debateTokens.input,\n output: tokensUsed.output + debateTokens.output,\n },\n };\n\n // Record analysis to knowledge base (async, don't block)\n this.recordToKnowledgeBase(validationResult).catch((err) => {\n console.warn('Failed to record to knowledge base:', err);\n });\n\n return validationResult;\n }\n\n /**\n * Record validation results to the knowledge base for pattern learning\n */\n private async recordToKnowledgeBase(result: ValidationResult): Promise<void> {\n const collector = getPatternCollector();\n const frameworks = this.frameworkContext?.frameworks || [];\n const languages = this.frameworkContext?.languages || [];\n\n // Build drift items from verified requirements\n const driftItems = result.verified\n .filter((v) => v.status === 'drift' && v.drift)\n .map((v) => ({\n description: v.drift!.description,\n category: v.requirement.category,\n severity: v.drift!.severity,\n sourceFile: v.requirement.sourceFile,\n accepted: true, // Default to accepted\n }));\n\n // Create anonymized report using proper function signature\n const report = anonymizeAnalysisReport(\n 'project', // Placeholder - actual path anonymized\n frameworks,\n languages,\n {\n total: result.summary.total,\n verified: result.summary.verified,\n drift: result.summary.drift,\n undocumented: result.summary.undocumented,\n unimplemented: result.summary.unimplemented,\n driftItems,\n debatesTriggered: result.summary.debatesTriggered,\n debatesOverturned: result.summary.debatesOverturned,\n overallConfidence: result.summary.overallConfidence,\n },\n 0, // docsCount - not tracked here\n 0 // codeCount - not tracked here\n );\n\n await collector.recordAnalysis(report);\n\n this.emitEvent('validator:recorded_to_kb', {\n driftPatterns: report.driftTypes.length,\n frameworks,\n });\n }\n\n /**\n * Cross-validate requirements against code features\n */\n private async crossValidate(\n docRequirements: Requirement[],\n codeFeatures: Requirement[],\n mappings: RequirementMapping[],\n docsContent: string,\n codeContent: string\n ): Promise<{\n verified: VerifiedRequirement[];\n tokensUsed: { input: number; output: number };\n }> {\n // Pre-screen for likely drift areas using knowledge base\n let prescreenHints: string[] = [];\n let patternEnhancements = '';\n\n if (this.frameworkContext) {\n const matcher = getPatternMatcher();\n prescreenHints = matcher.prescreenForDrift(docsContent, codeContent, this.frameworkContext);\n patternEnhancements = matcher.generatePromptEnhancements(this.frameworkContext);\n\n if (prescreenHints.length > 0) {\n this.emitEvent('validator:prescreen_hints', { hints: prescreenHints });\n }\n }\n\n const systemPrompt = `You are a senior QA engineer specializing in specification verification.\nYour task is to cross-validate documentation requirements against code implementations.\n\nFor EACH requirement and feature, determine the verification status:\n\nStatus meanings:\n- VERIFIED: Documentation and code match. Implementation satisfies the requirement.\n- DRIFT: Documentation and code disagree. Specify what differs.\n- UNDOCUMENTED: Feature exists in code but not documented.\n- UNIMPLEMENTED: Requirement documented but not implemented.\n\nDrift severity:\n- CRITICAL: User-facing behavior differs (pricing, quotas, security)\n- HIGH: API contracts differ (endpoints, parameters, responses)\n- MEDIUM: Internal implementation differs from spec\n- LOW: Minor documentation gaps, code is correct\n\nOutput format:\n{\n \"requirements\": [\n {\n \"id\": \"R-001\",\n \"description\": \"COPY the full description from the input requirement\",\n \"category\": \"security\",\n \"status\": \"verified\",\n \"confidence\": 95,\n \"documentedBehavior\": \"What the docs specify\",\n \"implementedBehavior\": \"What the code actually does\",\n \"evidence\": {\n \"docReferences\": [\"docs/PRD.md:45\"],\n \"codeReferences\": [\"src/auth/login.ts:12-45\"]\n },\n \"drift\": null\n },\n {\n \"id\": \"R-002\",\n \"description\": \"Rate limiting at 100 requests per minute\",\n \"category\": \"api\",\n \"status\": \"drift\",\n \"confidence\": 85,\n \"documentedBehavior\": \"100 requests per minute limit\",\n \"implementedBehavior\": \"50 requests per minute implemented\",\n \"evidence\": {\n \"docReferences\": [\"docs/API.md:22\"],\n \"codeReferences\": [\"src/middleware/rate-limit.ts:15\"]\n },\n \"drift\": {\n \"severity\": \"critical\",\n \"description\": \"Rate limit mismatch: docs say 100/min, code implements 50/min\",\n \"recommendation\": \"needs_discussion\"\n }\n }\n ]\n}\n\nIMPORTANT: Include ALL requirements AND all code features. Mark undocumented code features appropriately.\n\n${patternEnhancements}`;\n\n const docsReqJson = JSON.stringify(docRequirements, null, 2);\n const codeFeatJson = JSON.stringify(codeFeatures, null, 2);\n const mappingsJson = JSON.stringify(mappings, null, 2);\n\n // Build prescreen hints section if available\n const prescreenSection = prescreenHints.length > 0\n ? `\\n## PRE-SCREENED AREAS (likely drift):\\n${prescreenHints.map(h => `- ${h}`).join('\\n')}\\n`\n : '';\n\n const userMessage = `Cross-validate these requirements against code:\n${prescreenSection}\n## DOCUMENTATION REQUIREMENTS:\n${docsReqJson}\n\n## CODE FEATURES:\n${codeFeatJson}\n\n## PRELIMINARY MAPPINGS:\n${mappingsJson}\n\n## DOCUMENTATION CONTEXT:\n${docsContent.substring(0, 25000)}\n\n## CODE CONTEXT:\n${codeContent.substring(0, 25000)}\n\nAnalyze each item and return verification status.`;\n\n const result = await createJsonCompletion<{ requirements: VerifiedRequirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Build lookup for original data\n const docsLookup = new Map<string, Requirement>();\n const codeLookup = new Map<string, Requirement>();\n for (const req of docRequirements) {\n docsLookup.set(req.id, req);\n }\n for (const feat of codeFeatures) {\n codeLookup.set(feat.id, feat);\n }\n\n // Enrich with fallback data\n const verified: VerifiedRequirement[] = reqs.map((req) => {\n const id = req.requirement?.id || req.id || 'UNKNOWN';\n const originalDoc = docsLookup.get(id);\n const originalCode = codeLookup.get(id);\n const original = originalDoc || originalCode;\n\n // Get description with fallback\n let description = req.requirement?.description || req.description;\n if (!description || description === 'No description' || description.length < 10) {\n description = original?.description || 'No description available';\n }\n\n return {\n requirement: {\n id,\n description,\n category: req.requirement?.category || req.category || original?.category || 'feature',\n source: originalDoc ? 'docs' : originalCode ? 'code' : 'both',\n sourceFile: original?.sourceFile,\n sourceLine: original?.sourceLine,\n } as Requirement,\n status: (req.status || 'unimplemented') as VerificationStatus,\n confidence: req.confidence || 50,\n documentedBehavior: req.documentedBehavior,\n implementedBehavior: req.implementedBehavior,\n evidence: req.evidence || { docReferences: [], codeReferences: [] },\n drift: req.drift\n ? {\n severity: (req.drift.severity || 'medium') as DriftSeverity,\n description: req.drift.description || 'Drift detected',\n recommendation: req.drift.recommendation || 'needs_discussion',\n }\n : undefined,\n };\n });\n\n // Adjust confidence based on known patterns\n if (this.frameworkContext) {\n const matcher = getPatternMatcher();\n for (const item of verified) {\n if (item.status === 'drift' && item.drift) {\n // Find matching patterns for this drift\n const description = `${item.drift.description} ${item.requirement.description}`;\n const matches = matcher.matchDrift(description, this.frameworkContext);\n\n if (matches.length > 0) {\n // Adjust confidence based on best matching pattern\n const bestMatch = matches[0];\n const adjustedConfidence = matcher.adjustConfidence(item.confidence, bestMatch);\n item.confidence = adjustedConfidence;\n\n // Add pattern info to drift\n (item.drift as unknown as { patternKey: string }).patternKey = bestMatch.pattern.patternKey;\n }\n }\n }\n }\n\n // Apply calibration and track predictions\n if (this.enableCalibration) {\n const defaultContext: PredictionContext = {\n projectSize: 'medium',\n docType: 'other',\n codeType: 'fullstack',\n languages: this.frameworkContext?.languages || [],\n };\n\n for (const item of verified) {\n // Record prediction for tracking\n this.calibrationTracker.recordPrediction(\n item.requirement.id,\n item.status,\n item.confidence,\n item.requirement.category,\n defaultContext,\n {\n framework: this.frameworkContext?.frameworks?.[0],\n patternKey: (item.drift as unknown as { patternKey?: string })?.patternKey,\n }\n );\n\n // Apply calibration to confidence score\n const calibratedConfidence = this.confidenceCalibrator.calibrate(\n item.confidence,\n item.requirement.category,\n this.frameworkContext?.frameworks?.[0],\n (item.drift as unknown as { patternKey?: string })?.patternKey\n );\n item.confidence = calibratedConfidence;\n }\n }\n\n return {\n verified,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Debate a low-confidence finding to improve accuracy\n */\n async debateFinding(\n finding: VerifiedRequirement,\n docsContent: string,\n codeContent: string\n ): Promise<{\n finding: VerifiedRequirement;\n tokensUsed: { input: number; output: number };\n }> {\n const rounds: DebateRound[] = [];\n let totalTokens = { input: 0, output: 0 };\n let currentFinding = { ...finding };\n\n for (let round = 1; round <= this.maxDebateRounds; round++) {\n // Step 1: Challenge the finding\n const challenge = await this.generateChallenge(currentFinding, docsContent, codeContent);\n totalTokens.input += challenge.tokensUsed.input;\n totalTokens.output += challenge.tokensUsed.output;\n\n // Step 2: Defend the finding\n const defense = await this.generateDefense(\n currentFinding,\n challenge.challenge,\n docsContent,\n codeContent\n );\n totalTokens.input += defense.tokensUsed.input;\n totalTokens.output += defense.tokensUsed.output;\n\n rounds.push({\n round,\n challenge: challenge.challenge,\n defense: defense.defense,\n });\n\n // Step 3: Judge the debate\n const judgment = await this.judgeDebate(\n currentFinding,\n challenge.challenge,\n defense.defense,\n docsContent,\n codeContent\n );\n totalTokens.input += judgment.tokensUsed.input;\n totalTokens.output += judgment.tokensUsed.output;\n\n rounds[rounds.length - 1].judgeNotes = judgment.notes;\n\n // Update finding based on judgment\n if (judgment.verdict === 'overturn') {\n currentFinding = {\n ...currentFinding,\n status: judgment.newStatus || currentFinding.status,\n confidence: judgment.newConfidence,\n drift: judgment.newDrift || currentFinding.drift,\n };\n } else if (judgment.verdict === 'uphold') {\n currentFinding = {\n ...currentFinding,\n confidence: Math.min(100, currentFinding.confidence + 10),\n };\n }\n\n // If confidence is now high enough, stop debating\n if (currentFinding.confidence >= this.confidenceThreshold) {\n break;\n }\n }\n\n // Record the debate\n const outcome: DebateRecord['outcome'] =\n currentFinding.status !== finding.status\n ? 'overturned'\n : currentFinding.confidence !== finding.confidence\n ? 'modified'\n : 'upheld';\n\n currentFinding.debate = {\n initiated: new Date().toISOString(),\n challenger: 'validator',\n defender: 'analyzer',\n rounds,\n outcome,\n finalConfidence: currentFinding.confidence,\n };\n\n return { finding: currentFinding, tokensUsed: totalTokens };\n }\n\n /**\n * Generate a challenge to the current finding\n */\n private async generateChallenge(\n finding: VerifiedRequirement,\n docsContent: string,\n codeContent: string\n ): Promise<{\n challenge: string;\n tokensUsed: { input: number; output: number };\n }> {\n const systemPrompt = `You are a devil's advocate reviewing a specification verification finding.\nYour job is to CHALLENGE the finding and look for reasons it might be WRONG.\n\nBe skeptical. Look for:\n- Evidence that contradicts the finding\n- Alternative interpretations\n- Missing context that would change the verdict\n- Edge cases not considered\n- Assumptions that might be wrong\n\nOutput a clear, specific challenge to the finding.`;\n\n const userMessage = `Challenge this verification finding:\n\nFINDING:\n${JSON.stringify(finding, null, 2)}\n\nDOCUMENTATION CONTEXT:\n${docsContent.substring(0, 15000)}\n\nCODE CONTEXT:\n${codeContent.substring(0, 15000)}\n\nProvide a specific challenge explaining why this finding might be incorrect.`;\n\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'fast',\n maxTokens: 2048,\n });\n\n return {\n challenge: result.content,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Generate a defense for the current finding\n */\n private async generateDefense(\n finding: VerifiedRequirement,\n challenge: string,\n docsContent: string,\n codeContent: string\n ): Promise<{\n defense: string;\n tokensUsed: { input: number; output: number };\n }> {\n const systemPrompt = `You are defending a specification verification finding against a challenge.\nYour job is to DEFEND the original finding with evidence and reasoning.\n\nAddress the specific points raised in the challenge.\nProvide concrete evidence from the documentation and code.\nAcknowledge valid criticisms if they exist.`;\n\n const userMessage = `Defend this verification finding against the challenge:\n\nORIGINAL FINDING:\n${JSON.stringify(finding, null, 2)}\n\nCHALLENGE:\n${challenge}\n\nDOCUMENTATION CONTEXT:\n${docsContent.substring(0, 15000)}\n\nCODE CONTEXT:\n${codeContent.substring(0, 15000)}\n\nProvide a specific defense explaining why the original finding is correct.`;\n\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'fast',\n maxTokens: 2048,\n });\n\n return {\n defense: result.content,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Judge the debate and determine outcome\n */\n private async judgeDebate(\n finding: VerifiedRequirement,\n challenge: string,\n defense: string,\n docsContent: string,\n codeContent: string\n ): Promise<{\n verdict: 'uphold' | 'overturn' | 'modify';\n newStatus?: VerificationStatus;\n newConfidence: number;\n newDrift?: VerifiedRequirement['drift'];\n notes: string;\n tokensUsed: { input: number; output: number };\n }> {\n const systemPrompt = `You are an impartial judge evaluating a debate about a specification verification finding.\n\nReview the original finding, challenge, and defense. Then render a verdict:\n\n- UPHOLD: The original finding is correct. Increase confidence.\n- OVERTURN: The challenge is right, change the finding status.\n- MODIFY: Adjust confidence or details, keep same status.\n\nOutput JSON:\n{\n \"verdict\": \"uphold|overturn|modify\",\n \"newStatus\": \"verified|drift|undocumented|unimplemented\" (only if overturning),\n \"newConfidence\": 75,\n \"newDrift\": {...} (only if changing drift),\n \"notes\": \"Brief explanation of your decision\"\n}`;\n\n const userMessage = `Judge this debate:\n\nORIGINAL FINDING:\n${JSON.stringify(finding, null, 2)}\n\nCHALLENGE:\n${challenge}\n\nDEFENSE:\n${defense}\n\nDOCS CONTEXT:\n${docsContent.substring(0, 10000)}\n\nCODE CONTEXT:\n${codeContent.substring(0, 10000)}\n\nRender your verdict.`;\n\n const result = await createJsonCompletion<{\n verdict: 'uphold' | 'overturn' | 'modify';\n newStatus?: VerificationStatus;\n newConfidence: number;\n newDrift?: VerifiedRequirement['drift'];\n notes: string;\n }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 1024,\n });\n\n return {\n ...result.data,\n newConfidence: result.data.newConfidence || finding.confidence,\n notes: result.data.notes || 'No notes provided',\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Re-score confidence for findings based on evidence strength\n */\n async scoreConfidence(\n findings: VerifiedRequirement[]\n ): Promise<VerifiedRequirement[]> {\n return findings.map((finding) => {\n let score = finding.confidence;\n\n // Boost for strong evidence\n const docRefs = finding.evidence?.docReferences?.length || 0;\n const codeRefs = finding.evidence?.codeReferences?.length || 0;\n if (docRefs > 0 && codeRefs > 0) score += 10;\n if (docRefs > 2 || codeRefs > 2) score += 5;\n\n // Penalize missing details\n if (!finding.documentedBehavior && finding.status !== 'undocumented') score -= 10;\n if (!finding.implementedBehavior && finding.status !== 'unimplemented') score -= 10;\n\n // Penalize vague descriptions\n if (finding.requirement.description.length < 20) score -= 15;\n\n // Ensure bounds\n score = Math.max(0, Math.min(100, score));\n\n return { ...finding, confidence: score };\n });\n }\n\n /**\n * Calculate overall confidence from result\n */\n private calculateOverallConfidence(result: unknown): number {\n if (!result) return 0;\n\n if (Array.isArray(result)) {\n const findings = result as VerifiedRequirement[];\n if (findings.length === 0) return 50;\n return Math.round(\n findings.reduce((sum, f) => sum + f.confidence, 0) / findings.length\n );\n }\n\n const validation = result as ValidationResult;\n if (validation.summary?.overallConfidence) {\n return validation.summary.overallConfidence;\n }\n\n return 75;\n }\n\n /**\n * Execute community rules against content\n * Returns rule validation results (no AI tokens used - rules are local)\n */\n private executeCommunityRules(\n docsContent: string,\n codeContent: string\n ): ValidationResult['ruleResults'] {\n // Build target from framework context\n const target: Partial<RuleTarget> = {};\n if (this.frameworkContext) {\n target.frameworks = this.frameworkContext.frameworks;\n target.languages = this.frameworkContext.languages;\n }\n\n // Execute all applicable rules\n const ruleResults = this.rulesRegistry.executeAllRules(docsContent, codeContent, target);\n\n // Build summary\n const passed = ruleResults.filter((r) => r.passed).length;\n const failed = ruleResults.filter((r) => !r.passed && r.severity === 'error').length;\n const warnings = ruleResults.filter((r) => !r.passed && r.severity === 'warning').length;\n\n return {\n results: ruleResults.map((r) => ({\n ruleId: r.ruleId,\n ruleName: r.ruleName,\n passed: r.passed,\n severity: r.severity,\n message: r.message,\n })),\n passed,\n failed,\n warnings,\n };\n }\n\n /**\n * Get the rules registry for external access\n */\n getRulesRegistry(): RulesRegistry {\n return this.rulesRegistry;\n }\n\n // ==========================================================================\n // Git Analysis Integration\n // ==========================================================================\n\n /**\n * Enhance verification results with git history analysis\n * Adds freshness scores, desync detection, and drift risk insights\n */\n async enhanceWithGitAnalysis(\n verified: VerifiedRequirement[],\n docPaths: string[],\n codePaths: string[]\n ): Promise<{\n enhancedVerified: VerifiedRequirement[];\n gitSummary: GitAnalysisSummary;\n }> {\n if (!this.freshnessAnalyzer || !this.syncDetector || !this.gitAnalyzer) {\n // Return unchanged if git analysis not available\n return {\n enhancedVerified: verified,\n gitSummary: {\n averageFreshness: 0,\n staleDocCount: 0,\n desyncPairCount: 0,\n highRiskFileCount: 0,\n overallDriftRisk: 'low',\n },\n };\n }\n\n // Check if valid git repo\n const isValid = await this.gitAnalyzer.isValidGitRepo();\n if (!isValid) {\n return {\n enhancedVerified: verified,\n gitSummary: {\n averageFreshness: 0,\n staleDocCount: 0,\n desyncPairCount: 0,\n highRiskFileCount: 0,\n overallDriftRisk: 'low',\n },\n };\n }\n\n this.emitEvent('validator:git_analysis_started', {\n docCount: docPaths.length,\n codeCount: codePaths.length,\n });\n\n // Get freshness for all docs\n const freshnessByDoc = await this.freshnessAnalyzer.getBulkFreshness(docPaths);\n const staleThreshold = 90; // days\n\n // Find stale documents\n const staleDocs = await this.freshnessAnalyzer.findStaleDocuments(docPaths);\n\n // Calculate average freshness\n const averageFreshness = await this.freshnessAnalyzer.calculateAverageFreshness(docPaths);\n\n // Detect desync pairs (limit for performance)\n const desyncPairs: DesyncResult[] = [];\n const codePathsToCheck = codePaths.slice(0, 15);\n const docPathsToCheck = docPaths.slice(0, 10);\n\n for (const codePath of codePathsToCheck) {\n for (const docPath of docPathsToCheck) {\n try {\n const desync = await this.syncDetector.detectDocCodeDesync(codePath, docPath);\n if (desync.desyncRisk !== 'low') {\n desyncPairs.push(desync);\n }\n } catch {\n // Skip files that can't be analyzed\n }\n }\n }\n\n // Calculate drift risk scores\n const riskScores: DriftRiskScore[] = [];\n for (const codePath of codePathsToCheck) {\n try {\n const risk = await this.syncDetector.calculateDriftRisk(codePath, docPaths);\n riskScores.push(risk);\n } catch {\n // Skip files that can't be analyzed\n }\n }\n\n const highRiskFiles = riskScores.filter(\n (r) => r.riskLevel === 'high' || r.riskLevel === 'critical'\n );\n\n // Enhance verified requirements with freshness data\n const enhancedVerified = verified.map((item) => {\n const enhanced = { ...item };\n\n // Find matching doc freshness from evidence\n const docRef = item.evidence?.docReferences?.[0];\n if (docRef) {\n // Extract file path from reference (e.g., \"docs/API.md:45\" -> \"docs/API.md\")\n const docFile = docRef.split(':')[0];\n const fullPath = docPaths.find((p) => p.endsWith(docFile) || p.includes(docFile));\n\n if (fullPath) {\n const freshness = freshnessByDoc.get(fullPath);\n if (freshness) {\n const docFreshnessInfo: DocFreshnessInfo = {\n freshnessScore: freshness.freshnessScore,\n daysSinceUpdate: freshness.daysSinceUpdate,\n lastAuthor: freshness.lastAuthor,\n isStale: freshness.daysSinceUpdate > staleThreshold,\n };\n\n // Add freshness info (using any cast to extend type)\n (enhanced as unknown as { docFreshness: DocFreshnessInfo }).docFreshness = docFreshnessInfo;\n\n // Boost confidence for drift findings if docs are stale\n if (freshness.daysSinceUpdate > staleThreshold && item.status === 'drift') {\n enhanced.confidence = Math.min(100, item.confidence + 10);\n (enhanced as unknown as { gitInsight: string }).gitInsight =\n `Documentation hasn't been updated in ${freshness.daysSinceUpdate} days`;\n }\n }\n }\n }\n\n return enhanced;\n });\n\n // Calculate overall drift risk\n const overallDriftRisk = this.calculateOverallDriftRisk(\n staleDocs.length,\n desyncPairs.length,\n highRiskFiles.length,\n docPaths.length\n );\n\n const gitSummary: GitAnalysisSummary = {\n averageFreshness: Math.round(averageFreshness),\n staleDocCount: staleDocs.length,\n desyncPairCount: desyncPairs.length,\n highRiskFileCount: highRiskFiles.length,\n overallDriftRisk,\n };\n\n this.emitEvent('validator:git_analysis_complete', gitSummary);\n\n return { enhancedVerified, gitSummary };\n }\n\n /**\n * Calculate overall drift risk level based on git analysis metrics\n */\n private calculateOverallDriftRisk(\n staleCount: number,\n desyncCount: number,\n highRiskCount: number,\n totalDocs: number\n ): 'critical' | 'high' | 'medium' | 'low' {\n if (totalDocs === 0) return 'low';\n\n const staleRatio = staleCount / totalDocs;\n\n // Critical: >50% stale docs, or >10 high-risk files, or >20 desync pairs\n if (staleRatio > 0.5 || highRiskCount > 10 || desyncCount > 20) {\n return 'critical';\n }\n\n // High: >25% stale docs, or >5 high-risk files, or >10 desync pairs\n if (staleRatio > 0.25 || highRiskCount > 5 || desyncCount > 10) {\n return 'high';\n }\n\n // Medium: >10% stale docs, or any high-risk files, or >5 desync pairs\n if (staleRatio > 0.1 || highRiskCount > 0 || desyncCount > 5) {\n return 'medium';\n }\n\n return 'low';\n }\n\n /**\n * Get quick freshness check for a single document\n */\n async getDocFreshness(docPath: string): Promise<FreshnessResult | null> {\n if (!this.freshnessAnalyzer) return null;\n\n try {\n return await this.freshnessAnalyzer.getDocFreshness(docPath);\n } catch {\n return null;\n }\n }\n\n /**\n * Get desync check between code and doc\n */\n async checkDesync(codePath: string, docPath: string): Promise<DesyncResult | null> {\n if (!this.syncDetector) return null;\n\n try {\n return await this.syncDetector.detectDocCodeDesync(codePath, docPath);\n } catch {\n return null;\n }\n }\n}\n","/**\n * Local Embeddings (TF-IDF Based)\n *\n * Zero-cost local embeddings using TF-IDF (Term Frequency-Inverse Document Frequency).\n * Provides fast similarity search without API calls.\n */\n\nimport { createHash } from 'crypto';\nimport {\n TextChunk,\n ChunkMetadata,\n EmbeddingResult,\n VectorIndex,\n SearchResult,\n SearchOptions,\n} from './types.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst STOP_WORDS = new Set([\n 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',\n 'of', 'with', 'by', 'from', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would',\n 'could', 'should', 'may', 'might', 'must', 'shall', 'can', 'need',\n 'this', 'that', 'these', 'those', 'it', 'its', 'as', 'if', 'then',\n 'than', 'so', 'such', 'no', 'not', 'only', 'same', 'also', 'just',\n]);\n\n// ============================================================================\n// Local Embeddings Class\n// ============================================================================\n\nexport class LocalEmbeddings {\n private vocabulary: Map<string, number> = new Map();\n private idf: Map<string, number> = new Map();\n private dimensions: number;\n\n constructor(dimensions = 512) {\n this.dimensions = dimensions;\n }\n\n /**\n * Tokenize and normalize text\n */\n private tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, ' ')\n .split(/\\s+/)\n .filter((token) => token.length > 2 && !STOP_WORDS.has(token));\n }\n\n /**\n * Build vocabulary from documents\n */\n buildVocabulary(documents: string[]): void {\n const documentFreq = new Map<string, number>();\n const allTokens = new Set<string>();\n\n // Count document frequency for each term\n for (const doc of documents) {\n const tokens = new Set(this.tokenize(doc));\n for (const token of tokens) {\n allTokens.add(token);\n documentFreq.set(token, (documentFreq.get(token) || 0) + 1);\n }\n }\n\n // Build vocabulary (top N most frequent terms)\n const sortedTokens = [...allTokens]\n .map((token) => ({ token, freq: documentFreq.get(token) || 0 }))\n .sort((a, b) => b.freq - a.freq)\n .slice(0, this.dimensions);\n\n this.vocabulary.clear();\n this.idf.clear();\n\n for (let i = 0; i < sortedTokens.length; i++) {\n const { token, freq } = sortedTokens[i];\n this.vocabulary.set(token, i);\n // IDF = log(N / df) where N is total docs and df is document frequency\n this.idf.set(token, Math.log(documents.length / (freq + 1)));\n }\n }\n\n /**\n * Generate TF-IDF embedding for text\n */\n embed(text: string): EmbeddingResult {\n const tokens = this.tokenize(text);\n const termFreq = new Map<string, number>();\n\n // Calculate term frequency\n for (const token of tokens) {\n termFreq.set(token, (termFreq.get(token) || 0) + 1);\n }\n\n // Create TF-IDF vector\n const embedding = new Array(this.dimensions).fill(0);\n const maxTf = Math.max(...termFreq.values(), 1);\n\n for (const [token, tf] of termFreq) {\n const idx = this.vocabulary.get(token);\n if (idx !== undefined) {\n const normalizedTf = tf / maxTf;\n const idfValue = this.idf.get(token) || 0;\n embedding[idx] = normalizedTf * idfValue;\n }\n }\n\n // L2 normalize\n const norm = Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0));\n if (norm > 0) {\n for (let i = 0; i < embedding.length; i++) {\n embedding[i] /= norm;\n }\n }\n\n return {\n embedding,\n tokens: tokens.length,\n };\n }\n\n /**\n * Cosine similarity between two vectors\n */\n cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n return denominator === 0 ? 0 : dotProduct / denominator;\n }\n\n /**\n * Search for similar chunks\n */\n search(\n query: string,\n chunks: TextChunk[],\n options: SearchOptions = {}\n ): SearchResult[] {\n const { topK = 10, threshold = 0.1, filter } = options;\n\n const queryEmbedding = this.embed(query).embedding;\n\n let results: SearchResult[] = [];\n\n for (const chunk of chunks) {\n // Apply filters\n if (filter) {\n if (filter.type && chunk.metadata.type !== filter.type) continue;\n if (filter.category && chunk.metadata.category !== filter.category) continue;\n if (filter.sourceFile && chunk.metadata.sourceFile !== filter.sourceFile) continue;\n }\n\n if (!chunk.embedding) continue;\n\n const score = this.cosineSimilarity(queryEmbedding, chunk.embedding);\n\n if (score >= threshold) {\n results.push({ chunk, score, rank: 0 });\n }\n }\n\n // Sort by score descending\n results.sort((a, b) => b.score - a.score);\n\n // Assign ranks and take top K\n results = results.slice(0, topK).map((r, idx) => ({\n ...r,\n rank: idx + 1,\n }));\n\n return results;\n }\n\n /**\n * Get vocabulary size\n */\n getVocabularySize(): number {\n return this.vocabulary.size;\n }\n\n /**\n * Export state for serialization\n */\n exportState(): { vocabulary: [string, number][]; idf: [string, number][]; dimensions: number } {\n return {\n vocabulary: [...this.vocabulary.entries()],\n idf: [...this.idf.entries()],\n dimensions: this.dimensions,\n };\n }\n\n /**\n * Import state from serialization\n */\n importState(state: { vocabulary: [string, number][]; idf: [string, number][]; dimensions: number }): void {\n this.vocabulary = new Map(state.vocabulary);\n this.idf = new Map(state.idf);\n this.dimensions = state.dimensions;\n }\n}\n\n// ============================================================================\n// Chunking Utilities\n// ============================================================================\n\nexport interface ChunkingOptions {\n maxChunkSize?: number;\n overlap?: number;\n preserveCodeBlocks?: boolean;\n}\n\n/**\n * Split text into chunks\n */\nexport function chunkText(\n text: string,\n metadata: Omit<ChunkMetadata, 'sourceLine'>,\n options: ChunkingOptions = {}\n): TextChunk[] {\n const { maxChunkSize = 1000, overlap = 100, preserveCodeBlocks = true } = options;\n\n const chunks: TextChunk[] = [];\n const lines = text.split('\\n');\n\n let currentChunk = '';\n let currentLine = 1;\n let chunkStartLine = 1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Check if adding this line would exceed max size\n if (currentChunk.length + line.length > maxChunkSize && currentChunk.length > 0) {\n // Save current chunk\n const id = createHash('md5')\n .update(`${metadata.sourceFile}:${chunkStartLine}:${currentChunk.substring(0, 50)}`)\n .digest('hex')\n .substring(0, 12);\n\n chunks.push({\n id,\n content: currentChunk.trim(),\n metadata: {\n ...metadata,\n sourceLine: chunkStartLine,\n },\n });\n\n // Start new chunk with overlap\n const overlapLines = currentChunk.split('\\n').slice(-Math.ceil(overlap / 50));\n currentChunk = overlapLines.join('\\n') + '\\n';\n chunkStartLine = currentLine - overlapLines.length;\n }\n\n currentChunk += line + '\\n';\n currentLine++;\n }\n\n // Don't forget the last chunk\n if (currentChunk.trim().length > 0) {\n const id = createHash('md5')\n .update(`${metadata.sourceFile}:${chunkStartLine}:${currentChunk.substring(0, 50)}`)\n .digest('hex')\n .substring(0, 12);\n\n chunks.push({\n id,\n content: currentChunk.trim(),\n metadata: {\n ...metadata,\n sourceLine: chunkStartLine,\n },\n });\n }\n\n return chunks;\n}\n\n/**\n * Smart chunk code files (respects function boundaries)\n */\nexport function chunkCode(\n code: string,\n metadata: Omit<ChunkMetadata, 'sourceLine'>,\n options: ChunkingOptions = {}\n): TextChunk[] {\n const { maxChunkSize = 2000 } = options;\n\n const chunks: TextChunk[] = [];\n const lines = code.split('\\n');\n\n // Pattern to detect function/class/method starts\n const blockStartPattern = /^(?:export\\s+)?(?:async\\s+)?(?:function|class|const\\s+\\w+\\s*=\\s*(?:async\\s*)?\\(|interface|type|enum)/;\n\n let currentChunk = '';\n let currentLine = 1;\n let chunkStartLine = 1;\n let braceDepth = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Count braces\n braceDepth += (line.match(/\\{/g) || []).length;\n braceDepth -= (line.match(/\\}/g) || []).length;\n\n // Check if we should start a new chunk\n const isBlockStart = blockStartPattern.test(trimmedLine);\n const shouldSplit = isBlockStart && braceDepth <= 1 && currentChunk.length > maxChunkSize / 2;\n\n if (shouldSplit && currentChunk.length > 0) {\n const id = createHash('md5')\n .update(`${metadata.sourceFile}:${chunkStartLine}:code`)\n .digest('hex')\n .substring(0, 12);\n\n chunks.push({\n id,\n content: currentChunk.trim(),\n metadata: {\n ...metadata,\n sourceLine: chunkStartLine,\n },\n });\n\n currentChunk = '';\n chunkStartLine = currentLine;\n }\n\n currentChunk += line + '\\n';\n currentLine++;\n\n // Force split if chunk gets too large\n if (currentChunk.length > maxChunkSize && braceDepth === 0) {\n const id = createHash('md5')\n .update(`${metadata.sourceFile}:${chunkStartLine}:code`)\n .digest('hex')\n .substring(0, 12);\n\n chunks.push({\n id,\n content: currentChunk.trim(),\n metadata: {\n ...metadata,\n sourceLine: chunkStartLine,\n },\n });\n\n currentChunk = '';\n chunkStartLine = currentLine;\n }\n }\n\n // Last chunk\n if (currentChunk.trim().length > 0) {\n const id = createHash('md5')\n .update(`${metadata.sourceFile}:${chunkStartLine}:code`)\n .digest('hex')\n .substring(0, 12);\n\n chunks.push({\n id,\n content: currentChunk.trim(),\n metadata: {\n ...metadata,\n sourceLine: chunkStartLine,\n },\n });\n }\n\n return chunks;\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet embeddingsInstance: LocalEmbeddings | null = null;\n\nexport function getLocalEmbeddings(): LocalEmbeddings {\n if (!embeddingsInstance) {\n embeddingsInstance = new LocalEmbeddings();\n }\n return embeddingsInstance;\n}\n","/**\n * Pre-Screening Module\n *\n * Uses embeddings to filter relevant content before sending to AI.\n * Reduces token usage by 50-70% by only including relevant sections.\n */\n\nimport {\n TextChunk,\n ChunkMetadata,\n VectorIndex,\n SearchResult,\n SearchOptions,\n PreScreeningResult,\n PreScreeningOptions,\n} from './types.js';\nimport {\n LocalEmbeddings,\n getLocalEmbeddings,\n chunkText,\n chunkCode,\n} from './local-embeddings.js';\n\n// ============================================================================\n// Pre-Screening Engine\n// ============================================================================\n\nexport class PreScreeningEngine {\n private embeddings: LocalEmbeddings;\n private index: VectorIndex | null = null;\n\n constructor(embeddings?: LocalEmbeddings) {\n this.embeddings = embeddings || getLocalEmbeddings();\n }\n\n /**\n * Build index from documents and code\n */\n buildIndex(\n docs: Array<{ content: string; path: string; category?: string }>,\n code: Array<{ content: string; path: string; language?: string; category?: string }>\n ): VectorIndex {\n const chunks: TextChunk[] = [];\n\n // Chunk documents\n for (const doc of docs) {\n const docChunks = chunkText(doc.content, {\n sourceFile: doc.path,\n type: 'doc',\n category: doc.category,\n });\n chunks.push(...docChunks);\n }\n\n // Chunk code (use smart chunking)\n for (const file of code) {\n const codeChunks = chunkCode(file.content, {\n sourceFile: file.path,\n type: 'code',\n category: file.category,\n language: file.language,\n });\n chunks.push(...codeChunks);\n }\n\n // Build vocabulary from all content\n const allContent = chunks.map((c) => c.content);\n this.embeddings.buildVocabulary(allContent);\n\n // Generate embeddings for all chunks\n for (const chunk of chunks) {\n const result = this.embeddings.embed(chunk.content);\n chunk.embedding = result.embedding;\n }\n\n this.index = {\n chunks,\n provider: 'local',\n dimensions: this.embeddings.getVocabularySize(),\n };\n\n return this.index;\n }\n\n /**\n * Pre-screen content for a specific query/task\n */\n preScreen(options: PreScreeningOptions): PreScreeningResult {\n const startTime = Date.now();\n\n if (!this.index) {\n throw new Error('Index not built. Call buildIndex() first.');\n }\n\n const { query, maxChunks = 20, minRelevance = 0.15, includeTypes } = options;\n\n // Build search filter\n const filter: SearchOptions['filter'] = {};\n if (includeTypes && includeTypes.length > 0) {\n // We'll filter manually since our filter only supports single type\n // This is handled below\n }\n\n // Search for relevant chunks\n let results = this.embeddings.search(query, this.index.chunks, {\n topK: maxChunks * 2, // Get more initially for filtering\n threshold: minRelevance,\n });\n\n // Filter by types if specified\n if (includeTypes && includeTypes.length > 0) {\n results = results.filter((r) => includeTypes.includes(r.chunk.metadata.type));\n }\n\n // Take top K\n results = results.slice(0, maxChunks);\n\n const relevantChunks = results.map((r) => r.chunk);\n\n // Calculate token reduction\n const totalTokens = this.index.chunks.reduce(\n (sum, c) => sum + this.estimateTokens(c.content),\n 0\n );\n const reducedTokens = relevantChunks.reduce(\n (sum, c) => sum + this.estimateTokens(c.content),\n 0\n );\n const tokensSaved = totalTokens - reducedTokens;\n const reductionPercent = totalTokens > 0 ? Math.round((tokensSaved / totalTokens) * 100) : 0;\n\n return {\n relevantChunks,\n totalChunks: this.index.chunks.length,\n reducedTokens: tokensSaved,\n reductionPercent,\n searchTime: Date.now() - startTime,\n };\n }\n\n /**\n * Pre-screen for requirements extraction\n */\n preScreenForRequirements(\n docsContent: string,\n codeContent: string,\n framework?: string\n ): { docs: string; code: string; stats: PreScreeningResult } {\n // If no index, build one from the provided content\n if (!this.index) {\n this.buildIndex(\n [{ content: docsContent, path: 'docs', category: 'prd' }],\n [{ content: codeContent, path: 'code', category: 'routes' }]\n );\n }\n\n // Pre-screen for requirement-related content\n const query = `requirements features api endpoints authentication authorization\n validation security performance database models schemas routes handlers\n ${framework || ''} implementation specification behavior`;\n\n const result = this.preScreen({\n query,\n maxChunks: 30,\n minRelevance: 0.1,\n });\n\n // Separate docs and code chunks\n const docChunks = result.relevantChunks.filter((c) => c.metadata.type === 'doc');\n const codeChunks = result.relevantChunks.filter((c) => c.metadata.type === 'code');\n\n // Reconstruct content from chunks\n const relevantDocs = docChunks\n .sort((a, b) => (a.metadata.sourceLine || 0) - (b.metadata.sourceLine || 0))\n .map((c) => `[${c.metadata.sourceFile}:${c.metadata.sourceLine}]\\n${c.content}`)\n .join('\\n\\n---\\n\\n');\n\n const relevantCode = codeChunks\n .sort((a, b) => (a.metadata.sourceLine || 0) - (b.metadata.sourceLine || 0))\n .map((c) => `[${c.metadata.sourceFile}:${c.metadata.sourceLine}]\\n${c.content}`)\n .join('\\n\\n---\\n\\n');\n\n return {\n docs: relevantDocs || docsContent.substring(0, 50000), // Fallback to truncated original\n code: relevantCode || codeContent.substring(0, 50000),\n stats: result,\n };\n }\n\n /**\n * Pre-screen for specific feature/requirement verification\n */\n preScreenForVerification(\n requirement: string,\n codeChunks?: TextChunk[]\n ): SearchResult[] {\n if (!this.index && !codeChunks) {\n throw new Error('No index or chunks available');\n }\n\n const chunks = codeChunks || this.index!.chunks.filter((c) => c.metadata.type === 'code');\n\n return this.embeddings.search(requirement, chunks, {\n topK: 5,\n threshold: 0.2,\n });\n }\n\n /**\n * Estimate token count (rough approximation)\n */\n private estimateTokens(text: string): number {\n // Rough estimate: ~4 characters per token\n return Math.ceil(text.length / 4);\n }\n\n /**\n * Get index stats\n */\n getIndexStats(): {\n totalChunks: number;\n docChunks: number;\n codeChunks: number;\n vocabularySize: number;\n estimatedTokens: number;\n } | null {\n if (!this.index) return null;\n\n const docChunks = this.index.chunks.filter((c) => c.metadata.type === 'doc').length;\n const codeChunks = this.index.chunks.filter((c) => c.metadata.type === 'code').length;\n const estimatedTokens = this.index.chunks.reduce(\n (sum, c) => sum + this.estimateTokens(c.content),\n 0\n );\n\n return {\n totalChunks: this.index.chunks.length,\n docChunks,\n codeChunks,\n vocabularySize: this.embeddings.getVocabularySize(),\n estimatedTokens,\n };\n }\n\n /**\n * Clear the index\n */\n clearIndex(): void {\n this.index = null;\n }\n}\n\n// ============================================================================\n// Quick Pre-Screen Functions\n// ============================================================================\n\n/**\n * Quick pre-screen for a single query without building full index\n */\nexport function quickPreScreen(\n query: string,\n documents: Array<{ content: string; path: string; type: 'doc' | 'code' }>,\n options: { maxResults?: number; minRelevance?: number } = {}\n): SearchResult[] {\n const { maxResults = 10, minRelevance = 0.15 } = options;\n\n const embeddings = new LocalEmbeddings(256); // Smaller dimension for quick search\n\n // Build vocabulary from documents\n embeddings.buildVocabulary(documents.map((d) => d.content));\n\n // Create chunks with embeddings\n const chunks: TextChunk[] = documents.map((doc, idx) => {\n const result = embeddings.embed(doc.content);\n return {\n id: `quick-${idx}`,\n content: doc.content,\n metadata: {\n sourceFile: doc.path,\n type: doc.type,\n },\n embedding: result.embedding,\n };\n });\n\n // Search\n return embeddings.search(query, chunks, {\n topK: maxResults,\n threshold: minRelevance,\n });\n}\n\n/**\n * Estimate token savings from pre-screening\n */\nexport function estimateTokenSavings(\n originalDocs: string,\n originalCode: string,\n screenedDocs: string,\n screenedCode: string\n): {\n originalTokens: number;\n screenedTokens: number;\n savedTokens: number;\n savingsPercent: number;\n} {\n const estimateTokens = (text: string) => Math.ceil(text.length / 4);\n\n const originalTokens = estimateTokens(originalDocs) + estimateTokens(originalCode);\n const screenedTokens = estimateTokens(screenedDocs) + estimateTokens(screenedCode);\n const savedTokens = originalTokens - screenedTokens;\n const savingsPercent = originalTokens > 0\n ? Math.round((savedTokens / originalTokens) * 100)\n : 0;\n\n return {\n originalTokens,\n screenedTokens,\n savedTokens,\n savingsPercent,\n };\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet engineInstance: PreScreeningEngine | null = null;\n\nexport function getPreScreeningEngine(): PreScreeningEngine {\n if (!engineInstance) {\n engineInstance = new PreScreeningEngine();\n }\n return engineInstance;\n}\n\nexport function resetPreScreeningEngine(): void {\n engineInstance = null;\n}\n","/**\n * Embeddings Module\n *\n * Provides vector embeddings and pre-screening capabilities to reduce\n * AI token usage by 50-70%. Uses local TF-IDF embeddings for zero-cost\n * similarity search.\n *\n * Key Features:\n * - Local TF-IDF embeddings (no API cost)\n * - Smart document/code chunking\n * - Pre-screening for relevant content\n * - Significant token reduction for AI calls\n */\n\n// Types\nexport type {\n TextChunk,\n ChunkMetadata,\n EmbeddingProvider,\n EmbeddingConfig,\n EmbeddingResult,\n SearchResult,\n SearchOptions,\n VectorIndex,\n PreScreeningResult,\n PreScreeningOptions,\n} from './types.js';\n\n// Local Embeddings\nexport {\n LocalEmbeddings,\n getLocalEmbeddings,\n chunkText,\n chunkCode,\n} from './local-embeddings.js';\n\n// Pre-Screening\nexport {\n PreScreeningEngine,\n getPreScreeningEngine,\n resetPreScreeningEngine,\n quickPreScreen,\n estimateTokenSavings,\n} from './pre-screening.js';\n","/**\n * Base Specialist Agent\n *\n * Abstract base class for domain-specific verification agents.\n * Specialists focus on particular aspects of documentation-code verification:\n * - SecurityAgent: Authentication, authorization, input validation, OWASP\n * - APIContractAgent: Endpoints, schemas, HTTP methods, rate limits\n * - PerformanceAgent: SLAs, caching, query optimization, resource limits\n * - ComplianceAgent: GDPR, HIPAA, SOC2, audit logging, data retention\n */\n\nimport { BaseAgent } from '../base-agent.js';\nimport {\n TaskMessage,\n ResultMessage,\n VerifiedRequirement,\n Requirement,\n VerificationStatus,\n DriftSeverity,\n RequirementCategory,\n} from '../types.js';\nimport { createJsonCompletion } from '../../ai/client.js';\n\n// ============================================================================\n// Specialist Types\n// ============================================================================\n\nexport type SpecialtyType = 'security' | 'api-contract' | 'performance' | 'compliance';\n\nexport interface VerificationRule {\n id: string;\n name: string;\n description: string;\n severity: 'critical' | 'high' | 'medium' | 'low';\n category: RequirementCategory;\n pattern?: RegExp;\n check?: (docs: string, code: string) => boolean;\n}\n\nexport interface SpecialistFinding {\n requirement: Requirement;\n status: VerificationStatus;\n confidence: number;\n documentedBehavior?: string;\n implementedBehavior?: string;\n evidence: {\n docReferences: string[];\n codeReferences: string[];\n };\n drift?: {\n severity: DriftSeverity;\n description: string;\n recommendation: 'update_docs' | 'update_code' | 'needs_discussion';\n };\n specialistNotes?: string;\n}\n\nexport interface SpecialistResult {\n specialty: SpecialtyType;\n findings: SpecialistFinding[];\n summary: {\n totalChecked: number;\n issues: number;\n critical: number;\n high: number;\n medium: number;\n low: number;\n };\n tokensUsed: { input: number; output: number };\n executionTime: number;\n}\n\nexport interface SpecialistTaskInputs {\n docsContent: string;\n codeContent: string;\n existingFindings?: VerifiedRequirement[];\n focusAreas?: string[];\n}\n\n// ============================================================================\n// Base Specialist Agent\n// ============================================================================\n\nexport abstract class BaseSpecialistAgent extends BaseAgent {\n abstract readonly specialty: SpecialtyType;\n\n /**\n * Get domain-specific prompt context for LLM analysis\n */\n abstract getPromptContext(): string;\n\n /**\n * Get verification rules specific to this domain\n */\n abstract getVerificationRules(): VerificationRule[];\n\n /**\n * Get categories this specialist focuses on\n */\n abstract getFocusCategories(): RequirementCategory[];\n\n constructor() {\n super('specialist');\n }\n\n async execute(task: TaskMessage): Promise<ResultMessage> {\n const startTime = Date.now();\n this.status = 'executing';\n this.emitEvent('agent:task_started', { taskId: task.payload.taskId, specialty: this.specialty });\n\n try {\n const { taskType, inputs } = task.payload;\n const specialistInputs = inputs as unknown as SpecialistTaskInputs;\n\n let result: SpecialistResult;\n\n switch (taskType) {\n case 'specialist_verify':\n result = await this.verify(\n specialistInputs.docsContent,\n specialistInputs.codeContent,\n specialistInputs.existingFindings,\n specialistInputs.focusAreas\n );\n break;\n case 'specialist_enhance':\n result = await this.enhanceFindings(\n specialistInputs.existingFindings || [],\n specialistInputs.docsContent,\n specialistInputs.codeContent\n );\n break;\n default:\n throw new Error(`Unknown specialist task type: ${taskType}`);\n }\n\n const executionTime = Date.now() - startTime;\n this.addTokens(result.tokensUsed.input, result.tokensUsed.output);\n this.tasksCompleted++;\n this.status = 'complete';\n this.emitEvent('agent:task_completed', { taskId: task.payload.taskId, success: true });\n\n return this.createSuccessResult(\n task.payload.taskId,\n result,\n this.calculateResultConfidence(result),\n result.tokensUsed,\n executionTime\n );\n } catch (err) {\n const executionTime = Date.now() - startTime;\n const error = err instanceof Error ? err.message : 'Unknown error';\n this.status = 'error';\n\n return this.createErrorResult(task.payload.taskId, error, executionTime);\n }\n }\n\n /**\n * Main verification: analyze docs and code for domain-specific issues\n */\n async verify(\n docsContent: string,\n codeContent: string,\n existingFindings?: VerifiedRequirement[],\n focusAreas?: string[]\n ): Promise<SpecialistResult> {\n const startTime = Date.now();\n\n // Step 1: Run rule-based checks\n const ruleFindings = this.runRuleChecks(docsContent, codeContent);\n\n // Step 2: Run LLM analysis for deeper verification\n const llmFindings = await this.runLLMAnalysis(docsContent, codeContent, focusAreas);\n\n // Step 3: Merge findings, preferring LLM for confidence when overlapping\n const mergedFindings = this.mergeFindings(ruleFindings, llmFindings.findings);\n\n // Step 4: Cross-reference with existing findings if provided\n const finalFindings = existingFindings\n ? this.crossReferenceFindings(mergedFindings, existingFindings)\n : mergedFindings;\n\n const executionTime = Date.now() - startTime;\n\n return {\n specialty: this.specialty,\n findings: finalFindings,\n summary: this.calculateSummary(finalFindings),\n tokensUsed: llmFindings.tokensUsed,\n executionTime,\n };\n }\n\n /**\n * Enhance existing findings with domain expertise\n */\n async enhanceFindings(\n existingFindings: VerifiedRequirement[],\n docsContent: string,\n codeContent: string\n ): Promise<SpecialistResult> {\n const startTime = Date.now();\n\n // Filter findings relevant to this specialty\n const relevantFindings = existingFindings.filter((f) =>\n this.getFocusCategories().includes(f.requirement.category)\n );\n\n if (relevantFindings.length === 0) {\n return {\n specialty: this.specialty,\n findings: [],\n summary: this.calculateSummary([]),\n tokensUsed: { input: 0, output: 0 },\n executionTime: Date.now() - startTime,\n };\n }\n\n // Enhance each relevant finding with specialist analysis\n const enhancedResult = await this.enhanceWithSpecialistAnalysis(\n relevantFindings,\n docsContent,\n codeContent\n );\n\n return {\n specialty: this.specialty,\n findings: enhancedResult.findings,\n summary: this.calculateSummary(enhancedResult.findings),\n tokensUsed: enhancedResult.tokensUsed,\n executionTime: Date.now() - startTime,\n };\n }\n\n /**\n * Run pattern-based rule checks\n */\n protected runRuleChecks(docsContent: string, codeContent: string): SpecialistFinding[] {\n const findings: SpecialistFinding[] = [];\n const rules = this.getVerificationRules();\n\n for (const rule of rules) {\n if (rule.check) {\n const hasIssue = rule.check(docsContent, codeContent);\n if (hasIssue) {\n findings.push({\n requirement: {\n id: `${this.specialty}-${rule.id}`,\n description: rule.description,\n category: rule.category,\n source: 'both',\n },\n status: 'drift',\n confidence: 80, // Rule-based findings have moderate confidence\n evidence: {\n docReferences: [],\n codeReferences: [],\n },\n drift: {\n severity: rule.severity,\n description: `Rule violation: ${rule.name}`,\n recommendation: 'needs_discussion',\n },\n specialistNotes: `Detected by ${this.specialty} rule: ${rule.name}`,\n });\n }\n }\n\n if (rule.pattern) {\n const docsMatch = rule.pattern.test(docsContent);\n const codeMatch = rule.pattern.test(codeContent);\n\n if (docsMatch !== codeMatch) {\n findings.push({\n requirement: {\n id: `${this.specialty}-${rule.id}`,\n description: rule.description,\n category: rule.category,\n source: docsMatch ? 'docs' : 'code',\n },\n status: docsMatch && !codeMatch ? 'unimplemented' : 'undocumented',\n confidence: 75,\n documentedBehavior: docsMatch ? 'Pattern found in documentation' : undefined,\n implementedBehavior: codeMatch ? 'Pattern found in code' : undefined,\n evidence: {\n docReferences: docsMatch ? ['Pattern matched in docs'] : [],\n codeReferences: codeMatch ? ['Pattern matched in code'] : [],\n },\n specialistNotes: `Pattern check: ${rule.name}`,\n });\n }\n }\n }\n\n return findings;\n }\n\n /**\n * Run LLM-based analysis for deeper verification\n */\n protected async runLLMAnalysis(\n docsContent: string,\n codeContent: string,\n focusAreas?: string[]\n ): Promise<{ findings: SpecialistFinding[]; tokensUsed: { input: number; output: number } }> {\n const systemPrompt = this.buildSystemPrompt(focusAreas);\n\n const userMessage = `Analyze the following documentation and code for ${this.specialty} issues:\n\n## DOCUMENTATION:\n${docsContent.substring(0, 20000)}\n\n## CODE:\n${codeContent.substring(0, 20000)}\n\n${focusAreas?.length ? `\\nFOCUS AREAS: ${focusAreas.join(', ')}` : ''}\n\nIdentify any ${this.specialty} issues, discrepancies, or gaps.\n\nOutput JSON:\n{\n \"findings\": [\n {\n \"id\": \"unique-id\",\n \"description\": \"Description of the requirement or feature\",\n \"category\": \"${this.getFocusCategories()[0]}\",\n \"status\": \"verified|drift|undocumented|unimplemented\",\n \"confidence\": 85,\n \"documentedBehavior\": \"What docs say\",\n \"implementedBehavior\": \"What code does\",\n \"evidence\": {\n \"docReferences\": [\"file:line\"],\n \"codeReferences\": [\"file:line\"]\n },\n \"drift\": {\n \"severity\": \"critical|high|medium|low\",\n \"description\": \"Specific issue\",\n \"recommendation\": \"update_docs|update_code|needs_discussion\"\n },\n \"specialistNotes\": \"Domain-specific insight\"\n }\n ]\n}`;\n\n const result = await createJsonCompletion<{ findings: SpecialistFinding[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 8192,\n });\n\n const findings = (result.data.findings || []).map((f) => ({\n ...f,\n requirement: {\n id: f.id || `${this.specialty}-${Date.now()}`,\n description: f.description || 'No description',\n category: f.category || this.getFocusCategories()[0],\n source: 'both' as const,\n },\n status: (f.status || 'drift') as VerificationStatus,\n confidence: f.confidence || 70,\n evidence: f.evidence || { docReferences: [], codeReferences: [] },\n }));\n\n return {\n findings,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Build the system prompt with domain context\n */\n protected buildSystemPrompt(focusAreas?: string[]): string {\n const domainContext = this.getPromptContext();\n const rules = this.getVerificationRules();\n\n return `You are a ${this.specialty} specialist conducting verification analysis.\n\n${domainContext}\n\n## VERIFICATION RULES TO CHECK:\n${rules.map((r) => `- ${r.name}: ${r.description} (${r.severity})`).join('\\n')}\n\n${focusAreas?.length ? `\\n## PRIORITY FOCUS AREAS:\\n${focusAreas.map((a) => `- ${a}`).join('\\n')}` : ''}\n\nBe thorough but precise. Only report genuine issues, not stylistic preferences.\nAssign appropriate severity:\n- CRITICAL: Security vulnerabilities, data loss risk, user-facing behavior differs\n- HIGH: API contract violations, authentication issues\n- MEDIUM: Implementation differs from spec, missing validation\n- LOW: Minor gaps, documentation clarity issues`;\n }\n\n /**\n * Enhance existing findings with specialist analysis\n */\n protected async enhanceWithSpecialistAnalysis(\n findings: VerifiedRequirement[],\n docsContent: string,\n codeContent: string\n ): Promise<{ findings: SpecialistFinding[]; tokensUsed: { input: number; output: number } }> {\n const systemPrompt = `You are a ${this.specialty} specialist reviewing verification findings.\n${this.getPromptContext()}\n\nReview each finding and provide specialist insights. You may:\n- Upgrade or downgrade severity based on domain knowledge\n- Add specific recommendations\n- Add specialist notes with domain context\n- Flag critical issues that need immediate attention`;\n\n const userMessage = `Review these findings as a ${this.specialty} specialist:\n\n## EXISTING FINDINGS:\n${JSON.stringify(findings, null, 2)}\n\n## DOCUMENTATION CONTEXT:\n${docsContent.substring(0, 15000)}\n\n## CODE CONTEXT:\n${codeContent.substring(0, 15000)}\n\nEnhance each finding with ${this.specialty} expertise.\n\nOutput JSON:\n{\n \"findings\": [\n {\n \"id\": \"original-id\",\n \"description\": \"Enhanced description\",\n \"category\": \"security\",\n \"status\": \"drift\",\n \"confidence\": 90,\n \"documentedBehavior\": \"...\",\n \"implementedBehavior\": \"...\",\n \"evidence\": {...},\n \"drift\": {...},\n \"specialistNotes\": \"Specialist insight\"\n }\n ]\n}`;\n\n const result = await createJsonCompletion<{ findings: SpecialistFinding[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 8192,\n });\n\n const enhancedFindings = (result.data.findings || []).map((f) => ({\n ...f,\n requirement: {\n id: f.id || `${this.specialty}-${Date.now()}`,\n description: f.description || 'No description',\n category: f.category || this.getFocusCategories()[0],\n source: 'both' as const,\n },\n status: (f.status || 'drift') as VerificationStatus,\n confidence: f.confidence || 70,\n evidence: f.evidence || { docReferences: [], codeReferences: [] },\n }));\n\n return {\n findings: enhancedFindings,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n }\n\n /**\n * Merge rule-based and LLM findings, deduplicating by similarity\n */\n protected mergeFindings(\n ruleFindings: SpecialistFinding[],\n llmFindings: SpecialistFinding[]\n ): SpecialistFinding[] {\n const merged: SpecialistFinding[] = [...llmFindings];\n\n for (const ruleFinding of ruleFindings) {\n // Check if LLM already found something similar\n const isDuplicate = llmFindings.some(\n (llmF) =>\n llmF.requirement.id === ruleFinding.requirement.id ||\n (llmF.drift?.description &&\n ruleFinding.drift?.description &&\n this.stringSimilarity(llmF.drift.description, ruleFinding.drift.description) > 0.7)\n );\n\n if (!isDuplicate) {\n merged.push(ruleFinding);\n }\n }\n\n return merged;\n }\n\n /**\n * Cross-reference with existing findings from other agents\n */\n protected crossReferenceFindings(\n specialistFindings: SpecialistFinding[],\n existingFindings: VerifiedRequirement[]\n ): SpecialistFinding[] {\n return specialistFindings.map((finding) => {\n // Look for matching existing finding\n const existing = existingFindings.find(\n (ef) =>\n ef.requirement.id === finding.requirement.id ||\n this.stringSimilarity(ef.requirement.description, finding.requirement.description) > 0.8\n );\n\n if (existing) {\n // Boost confidence if both found the same issue\n if (existing.status === finding.status) {\n finding.confidence = Math.min(100, finding.confidence + 10);\n }\n // Add cross-reference note\n finding.specialistNotes = `${finding.specialistNotes || ''} [Corroborated by general analysis]`.trim();\n }\n\n return finding;\n });\n }\n\n /**\n * Calculate summary statistics\n */\n protected calculateSummary(findings: SpecialistFinding[]): SpecialistResult['summary'] {\n const issues = findings.filter((f) => f.status !== 'verified');\n return {\n totalChecked: findings.length,\n issues: issues.length,\n critical: issues.filter((f) => f.drift?.severity === 'critical').length,\n high: issues.filter((f) => f.drift?.severity === 'high').length,\n medium: issues.filter((f) => f.drift?.severity === 'medium').length,\n low: issues.filter((f) => f.drift?.severity === 'low').length,\n };\n }\n\n /**\n * Calculate overall confidence from result\n */\n protected calculateResultConfidence(result: SpecialistResult): number {\n if (result.findings.length === 0) return 80;\n return Math.round(\n result.findings.reduce((sum, f) => sum + f.confidence, 0) / result.findings.length\n );\n }\n\n /**\n * Simple string similarity check (Jaccard-like)\n */\n protected stringSimilarity(a: string, b: string): number {\n const aWords = new Set(a.toLowerCase().split(/\\s+/));\n const bWords = new Set(b.toLowerCase().split(/\\s+/));\n const intersection = new Set([...aWords].filter((x) => bWords.has(x)));\n const union = new Set([...aWords, ...bWords]);\n return intersection.size / union.size;\n }\n}\n","/**\n * Security Specialist Agent\n *\n * Focuses on security-related verification:\n * - Authentication patterns (JWT, OAuth, sessions)\n * - Authorization checks (RBAC, permissions)\n * - Input validation and sanitization\n * - Secrets management\n * - OWASP Top 10 compliance\n */\n\nimport {\n BaseSpecialistAgent,\n SpecialtyType,\n VerificationRule,\n} from './base-specialist.js';\nimport type { RequirementCategory } from '../types.js';\n\nexport class SecurityAgent extends BaseSpecialistAgent {\n readonly specialty: SpecialtyType = 'security';\n\n getPromptContext(): string {\n return `You are a security specialist with expertise in:\n\n## Authentication\n- JWT token validation and expiration\n- OAuth 2.0 / OIDC flows\n- Session management\n- Multi-factor authentication\n- Password policies and hashing\n\n## Authorization\n- Role-Based Access Control (RBAC)\n- Attribute-Based Access Control (ABAC)\n- Permission checks before operations\n- Principle of least privilege\n\n## Input Validation\n- SQL injection prevention\n- XSS (Cross-Site Scripting) prevention\n- Command injection prevention\n- Path traversal prevention\n- Input sanitization and encoding\n\n## Secrets Management\n- API keys and credentials handling\n- Environment variable usage\n- Secrets rotation policies\n- No hardcoded secrets in code\n\n## OWASP Top 10 (2021)\n- A01: Broken Access Control\n- A02: Cryptographic Failures\n- A03: Injection\n- A04: Insecure Design\n- A05: Security Misconfiguration\n- A06: Vulnerable Components\n- A07: Auth/Session Issues\n- A08: Data Integrity Failures\n- A09: Logging/Monitoring Failures\n- A10: SSRF\n\nFocus on CRITICAL issues that could lead to:\n- Unauthorized access to data or systems\n- Data breaches or leaks\n- Privilege escalation\n- Denial of service`;\n }\n\n getVerificationRules(): VerificationRule[] {\n return [\n // Authentication rules\n {\n id: 'sec-001',\n name: 'JWT Expiration Documented',\n description: 'JWT token expiration should be documented and match implementation',\n severity: 'high',\n category: 'security',\n pattern: /jwt|token.*expir|expir.*token|access.*token/i,\n },\n {\n id: 'sec-002',\n name: 'Password Requirements',\n description: 'Password policy should be documented and enforced',\n severity: 'high',\n category: 'security',\n pattern: /password.*(?:policy|requir|minimum|length|complex)/i,\n },\n {\n id: 'sec-003',\n name: 'Session Timeout',\n description: 'Session timeout policy should be documented',\n severity: 'medium',\n category: 'security',\n pattern: /session.*(?:timeout|expir|idle)/i,\n },\n\n // Authorization rules\n {\n id: 'sec-010',\n name: 'RBAC Documentation',\n description: 'Role-based access control should be fully documented',\n severity: 'critical',\n category: 'security',\n pattern: /(?:role|permission|rbac|access.*control)/i,\n },\n {\n id: 'sec-011',\n name: 'Admin Privileges',\n description: 'Admin and elevated privileges should be clearly documented',\n severity: 'critical',\n category: 'security',\n pattern: /admin|superuser|elevated|privileged/i,\n },\n\n // Input validation rules\n {\n id: 'sec-020',\n name: 'Input Validation',\n description: 'Input validation requirements should match implementation',\n severity: 'high',\n category: 'security',\n pattern: /(?:sanitiz|validat|escape|encod).*(?:input|user|data)/i,\n },\n {\n id: 'sec-021',\n name: 'SQL Injection Prevention',\n description: 'SQL injection prevention measures should be documented',\n severity: 'critical',\n category: 'security',\n check: (docs, code) => {\n const docsHasSQLInfo = /sql.*(?:inject|parameteriz|prepared)/i.test(docs);\n const codeHasRawSQL = /(?:query|exec)\\s*\\(\\s*[`'\"].*\\$\\{|\\.query\\s*\\([^)]*\\+/i.test(code);\n return codeHasRawSQL && !docsHasSQLInfo;\n },\n },\n\n // Secrets management rules\n {\n id: 'sec-030',\n name: 'No Hardcoded Secrets',\n description: 'Secrets should not be hardcoded in source code',\n severity: 'critical',\n category: 'security',\n check: (_docs, code) => {\n // Look for potential hardcoded secrets\n const secretPatterns = [\n /(?:api[_-]?key|apikey)\\s*[:=]\\s*['\"][a-zA-Z0-9]{20,}['\"]/i,\n /(?:secret|password)\\s*[:=]\\s*['\"][^'\"]{8,}['\"]/i,\n /(?:aws|gcp|azure).*(?:key|secret)\\s*[:=]\\s*['\"][^'\"]+['\"]/i,\n /sk[-_](?:live|test)[-_][a-zA-Z0-9]{20,}/i, // Stripe keys\n /ghp_[a-zA-Z0-9]{36}/i, // GitHub tokens\n ];\n return secretPatterns.some((p) => p.test(code));\n },\n },\n {\n id: 'sec-031',\n name: 'Environment Variables for Secrets',\n description: 'Secrets should be loaded from environment variables',\n severity: 'high',\n category: 'security',\n pattern: /(?:process\\.env|os\\.environ|getenv)\\s*\\[?\\s*['\"](?:API|SECRET|KEY|PASSWORD|TOKEN)/i,\n },\n\n // HTTPS/TLS rules\n {\n id: 'sec-040',\n name: 'HTTPS Required',\n description: 'HTTPS should be required for all API endpoints',\n severity: 'high',\n category: 'security',\n check: (docs, code) => {\n const docsRequiresHTTPS = /https.*required|tls.*required|secure.*connection/i.test(docs);\n const codeHasHTTP = /http:\\/\\/(?!localhost|127\\.0\\.0\\.1)/i.test(code);\n return codeHasHTTP && !docsRequiresHTTPS;\n },\n },\n\n // Rate limiting rules\n {\n id: 'sec-050',\n name: 'Rate Limiting Documented',\n description: 'Rate limiting should be documented for auth endpoints',\n severity: 'medium',\n category: 'security',\n pattern: /rate.*limit|throttl|brute.*force|login.*attempt/i,\n },\n\n // CORS rules\n {\n id: 'sec-060',\n name: 'CORS Configuration',\n description: 'CORS configuration should be documented',\n severity: 'medium',\n category: 'security',\n pattern: /cors|cross.*origin|allow.*origin/i,\n },\n\n // Audit logging rules\n {\n id: 'sec-070',\n name: 'Security Audit Logging',\n description: 'Security events should be logged',\n severity: 'high',\n category: 'security',\n pattern: /audit.*log|security.*log|login.*log|access.*log/i,\n },\n ];\n }\n\n getFocusCategories(): RequirementCategory[] {\n return ['security'];\n }\n}\n","/**\n * API Contract Specialist Agent\n *\n * Focuses on API contract verification:\n * - Endpoint URL patterns and routing\n * - Request/response schemas and validation\n * - HTTP methods and status codes\n * - Rate limiting documentation\n * - API versioning compliance\n */\n\nimport {\n BaseSpecialistAgent,\n SpecialtyType,\n VerificationRule,\n} from './base-specialist.js';\nimport type { RequirementCategory } from '../types.js';\n\nexport class APIContractAgent extends BaseSpecialistAgent {\n readonly specialty: SpecialtyType = 'api-contract';\n\n getPromptContext(): string {\n return `You are an API contract specialist with expertise in:\n\n## Endpoint Contracts\n- URL patterns and path parameters\n- Query parameter requirements\n- Request body schemas\n- Response schemas and structures\n- Content-Type headers\n\n## HTTP Semantics\n- Correct HTTP method usage (GET, POST, PUT, PATCH, DELETE)\n- Appropriate status codes for each scenario\n- Idempotency requirements\n- Safe vs unsafe operations\n\n## Request/Response Validation\n- Required vs optional fields\n- Field types and formats\n- Nested object structures\n- Array handling\n- Null/undefined handling\n\n## Rate Limiting & Quotas\n- Rate limit values (requests per minute/hour)\n- Quota limits (daily/monthly limits)\n- Rate limit headers (X-RateLimit-*)\n- Retry-After handling\n\n## API Versioning\n- URL versioning (/v1/, /v2/)\n- Header versioning (API-Version)\n- Deprecation policies\n- Breaking vs non-breaking changes\n\n## Error Handling\n- Error response format\n- Error codes and messages\n- Validation error details\n- Standard error schemas\n\nFocus on CONTRACT DRIFT where:\n- Documented endpoints don't exist in code\n- Code endpoints aren't documented\n- Request/response schemas differ\n- Status codes don't match documentation\n- Rate limits differ between docs and code`;\n }\n\n getVerificationRules(): VerificationRule[] {\n return [\n // Endpoint rules\n {\n id: 'api-001',\n name: 'REST Endpoint Documentation',\n description: 'All REST endpoints should be documented with method and path',\n severity: 'critical',\n category: 'api',\n pattern: /(?:GET|POST|PUT|PATCH|DELETE)\\s+\\/[a-zA-Z0-9\\/:_-]+/i,\n },\n {\n id: 'api-002',\n name: 'Path Parameters',\n description: 'Path parameters should be documented with types',\n severity: 'high',\n category: 'api',\n pattern: /:\\w+|{[^}]+}|\\[id\\]|\\[slug\\]/i,\n },\n {\n id: 'api-003',\n name: 'Query Parameters',\n description: 'Query parameters should be documented',\n severity: 'medium',\n category: 'api',\n pattern: /\\?.*=|query.*param|filter|sort|page|limit|offset/i,\n },\n\n // Request/Response rules\n {\n id: 'api-010',\n name: 'Request Body Schema',\n description: 'Request body schema should match documentation',\n severity: 'critical',\n category: 'api',\n pattern: /request.*body|body.*schema|payload|(?:type|interface)\\s+\\w+Request/i,\n },\n {\n id: 'api-011',\n name: 'Response Schema',\n description: 'Response schema should match documentation',\n severity: 'critical',\n category: 'api',\n pattern: /response.*(?:body|schema)|returns|(?:type|interface)\\s+\\w+Response/i,\n },\n {\n id: 'api-012',\n name: 'Content-Type Header',\n description: 'Content-Type should be documented',\n severity: 'medium',\n category: 'api',\n pattern: /content-type|application\\/json|multipart\\/form-data/i,\n },\n\n // HTTP Status codes\n {\n id: 'api-020',\n name: 'Success Status Codes',\n description: 'Success status codes (2xx) should be documented',\n severity: 'high',\n category: 'api',\n pattern: /(?:status|code).*(?:200|201|204)|(?:200|201|204).*(?:OK|Created|No Content)/i,\n },\n {\n id: 'api-021',\n name: 'Error Status Codes',\n description: 'Error status codes (4xx, 5xx) should be documented',\n severity: 'high',\n category: 'api',\n pattern: /(?:status|code).*(?:400|401|403|404|409|422|500)|(?:Bad Request|Unauthorized|Forbidden|Not Found)/i,\n },\n {\n id: 'api-022',\n name: 'Status Code Implementation',\n description: 'Documented status codes should be implemented',\n severity: 'high',\n category: 'api',\n check: (docs, code) => {\n // Check for common status codes in docs vs code\n const docsCodes = docs.match(/\\b(200|201|204|400|401|403|404|409|422|500)\\b/g) || [];\n const codeCodes = code.match(/(?:status|code|res\\.status)\\s*\\(?\\s*(200|201|204|400|401|403|404|409|422|500)/gi) || [];\n\n const docsSet = new Set(docsCodes);\n const codeSet = new Set(codeCodes.map((c) => c.match(/\\d+/)?.[0]).filter(Boolean));\n\n // Flag if docs have codes not in code\n for (const code of docsSet) {\n if (!codeSet.has(code)) return true;\n }\n return false;\n },\n },\n\n // Rate limiting rules\n {\n id: 'api-030',\n name: 'Rate Limit Documentation',\n description: 'Rate limits should be documented',\n severity: 'high',\n category: 'api',\n pattern: /rate.*limit|requests.*(?:per|\\/)\\s*(?:second|minute|hour)|throttl/i,\n },\n {\n id: 'api-031',\n name: 'Rate Limit Headers',\n description: 'Rate limit headers should be documented',\n severity: 'medium',\n category: 'api',\n pattern: /x-ratelimit|ratelimit-remaining|retry-after/i,\n },\n {\n id: 'api-032',\n name: 'Rate Limit Values Match',\n description: 'Rate limit values in docs should match code',\n severity: 'critical',\n category: 'api',\n check: (docs, code) => {\n // Extract rate limit numbers from both\n const docsLimits = docs.match(/(\\d+)\\s*(?:requests?|req)?\\s*(?:per|\\/)\\s*(?:second|minute|hour|day)/gi) || [];\n const codeLimits = code.match(/(?:limit|max|rate).*?(\\d+)|(\\d+).*(?:limit|max|rate)/gi) || [];\n\n if (docsLimits.length > 0 && codeLimits.length > 0) {\n const docsNums = docsLimits.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n const codeNums = codeLimits.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n\n // Check if any documented limit isn't in code\n for (const num of docsNums) {\n if (!codeNums.includes(num)) return true;\n }\n }\n return false;\n },\n },\n\n // Versioning rules\n {\n id: 'api-040',\n name: 'API Version Documentation',\n description: 'API version should be documented',\n severity: 'medium',\n category: 'api',\n pattern: /\\/v\\d+\\/|api.*version|version.*api|api-version/i,\n },\n {\n id: 'api-041',\n name: 'Deprecation Notice',\n description: 'Deprecated endpoints should be marked',\n severity: 'medium',\n category: 'api',\n pattern: /deprecat|sunset|end.*of.*life|eol/i,\n },\n\n // Error handling rules\n {\n id: 'api-050',\n name: 'Error Response Format',\n description: 'Error response format should be documented',\n severity: 'high',\n category: 'api',\n pattern: /error.*(?:response|format|schema)|(?:message|code|details).*error/i,\n },\n {\n id: 'api-051',\n name: 'Validation Error Details',\n description: 'Validation errors should include field-level details',\n severity: 'medium',\n category: 'api',\n pattern: /validation.*error|field.*error|invalid.*field/i,\n },\n\n // Pagination rules\n {\n id: 'api-060',\n name: 'Pagination Documentation',\n description: 'List endpoints should document pagination',\n severity: 'medium',\n category: 'api',\n pattern: /pagination|page.*size|limit.*offset|cursor|next.*page/i,\n },\n\n // Authentication rules (API-specific)\n {\n id: 'api-070',\n name: 'Authentication Method',\n description: 'API authentication method should be documented',\n severity: 'critical',\n category: 'api',\n pattern: /bearer.*token|api.*key|oauth|basic.*auth|authorization.*header/i,\n },\n ];\n }\n\n getFocusCategories(): RequirementCategory[] {\n return ['api', 'integration'];\n }\n}\n","/**\n * Performance Specialist Agent\n *\n * Focuses on performance-related verification:\n * - Documented SLAs vs implementation\n * - Caching strategies and TTLs\n * - Query optimization claims\n * - Batch processing limits\n * - Memory/resource constraints\n */\n\nimport {\n BaseSpecialistAgent,\n SpecialtyType,\n VerificationRule,\n} from './base-specialist.js';\nimport type { RequirementCategory } from '../types.js';\n\nexport class PerformanceAgent extends BaseSpecialistAgent {\n readonly specialty: SpecialtyType = 'performance';\n\n getPromptContext(): string {\n return `You are a performance specialist with expertise in:\n\n## Service Level Agreements (SLAs)\n- Response time guarantees (p50, p95, p99)\n- Uptime commitments (99.9%, 99.99%)\n- Throughput targets (requests per second)\n- Availability windows\n\n## Caching Strategies\n- Cache TTL (Time To Live) values\n- Cache invalidation policies\n- Cache-Control headers\n- CDN caching rules\n- In-memory vs distributed caching\n\n## Database Performance\n- Query optimization (indexes, query plans)\n- Connection pooling configuration\n- Read replicas and load balancing\n- N+1 query prevention\n- Batch query limits\n\n## Resource Limits\n- Memory limits and allocation\n- CPU constraints\n- File size limits\n- Concurrent connection limits\n- Request/response size limits\n\n## Batch Processing\n- Batch size limits\n- Bulk operation limits\n- Pagination requirements\n- Timeout configurations\n\n## Async Operations\n- Queue processing times\n- Webhook delivery guarantees\n- Retry policies\n- Timeout configurations\n\nFocus on PERFORMANCE DRIFT where:\n- Documented SLAs differ from implemented timeouts\n- Cache TTLs in code don't match documentation\n- Batch limits differ between docs and code\n- Resource limits aren't enforced as documented\n- Query patterns don't match optimization claims`;\n }\n\n getVerificationRules(): VerificationRule[] {\n return [\n // SLA rules\n {\n id: 'perf-001',\n name: 'Response Time SLA',\n description: 'Response time SLAs should be documented and implemented',\n severity: 'high',\n category: 'performance',\n pattern: /response.*time|latency|(?:p50|p95|p99)|millisecond|ms.*(?:target|sla|limit)/i,\n },\n {\n id: 'perf-002',\n name: 'Uptime SLA',\n description: 'Uptime guarantees should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /uptime|availability|(?:99\\.9|99\\.99)%|sla/i,\n },\n {\n id: 'perf-003',\n name: 'Throughput Targets',\n description: 'Throughput targets should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /throughput|requests.*(?:per|\\/)\\s*(?:second|minute)|rps|qps/i,\n },\n\n // Caching rules\n {\n id: 'perf-010',\n name: 'Cache TTL Documentation',\n description: 'Cache TTL values should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /cache.*(?:ttl|expir|duration)|ttl|time.*to.*live/i,\n },\n {\n id: 'perf-011',\n name: 'Cache TTL Match',\n description: 'Cache TTL in docs should match code implementation',\n severity: 'high',\n category: 'performance',\n check: (docs, code) => {\n // Extract TTL values from docs\n const docsTTL = docs.match(/(?:ttl|cache|expir).*?(\\d+)\\s*(?:second|minute|hour|day|s|m|h|d)/gi) || [];\n // Extract TTL from code\n const codeTTL = code.match(/(?:ttl|maxAge|expire|cache).*?(\\d+)|(\\d+).*(?:ttl|maxAge|expire)/gi) || [];\n\n if (docsTTL.length > 0 && codeTTL.length > 0) {\n const docsNums = docsTTL.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n const codeNums = codeTTL.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n\n // Check if any documented TTL isn't in code\n for (const num of docsNums) {\n if (!codeNums.includes(num)) return true;\n }\n }\n return false;\n },\n },\n {\n id: 'perf-012',\n name: 'Cache-Control Headers',\n description: 'Cache-Control headers should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /cache-control|max-age|no-cache|no-store|must-revalidate/i,\n },\n {\n id: 'perf-013',\n name: 'Cache Invalidation',\n description: 'Cache invalidation strategy should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /cache.*invalid|clear.*cache|purge|bust.*cache/i,\n },\n\n // Database rules\n {\n id: 'perf-020',\n name: 'Database Indexing',\n description: 'Database indexes should be documented for query optimization',\n severity: 'medium',\n category: 'performance',\n pattern: /index|query.*optim|database.*perform/i,\n },\n {\n id: 'perf-021',\n name: 'Connection Pool Size',\n description: 'Database connection pool settings should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /connection.*pool|pool.*size|max.*connections/i,\n },\n {\n id: 'perf-022',\n name: 'Query Timeout',\n description: 'Query timeouts should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /query.*timeout|statement.*timeout|database.*timeout/i,\n },\n\n // Batch/Bulk rules\n {\n id: 'perf-030',\n name: 'Batch Size Limits',\n description: 'Batch operation size limits should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /batch.*(?:size|limit)|bulk.*(?:size|limit)|max.*(?:batch|bulk)/i,\n },\n {\n id: 'perf-031',\n name: 'Batch Size Match',\n description: 'Batch limits in docs should match code',\n severity: 'high',\n category: 'performance',\n check: (docs, code) => {\n // Check for batch size discrepancies\n const docsBatch = docs.match(/(?:batch|bulk).*?(\\d+)|(\\d+).*(?:batch|bulk)/gi) || [];\n const codeBatch = code.match(/(?:batchSize|bulkSize|maxBatch|BATCH_SIZE|BULK_LIMIT).*?(\\d+)|(\\d+).*(?:batch|bulk)/gi) || [];\n\n if (docsBatch.length > 0 && codeBatch.length > 0) {\n const docsNums = docsBatch.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n const codeNums = codeBatch.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n\n for (const num of docsNums) {\n if (!codeNums.includes(num)) return true;\n }\n }\n return false;\n },\n },\n {\n id: 'perf-032',\n name: 'Pagination Limits',\n description: 'Pagination limits should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /page.*size|limit|per.*page|max.*results/i,\n },\n\n // Resource limit rules\n {\n id: 'perf-040',\n name: 'File Size Limits',\n description: 'File upload/download size limits should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /file.*size|max.*(?:upload|download)|(?:mb|kb|gb).*limit/i,\n },\n {\n id: 'perf-041',\n name: 'Request Size Limit',\n description: 'Request body size limits should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /(?:request|body|payload).*(?:size|limit)|content-length.*limit/i,\n },\n {\n id: 'perf-042',\n name: 'Memory Limits',\n description: 'Memory limits and allocations should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /memory.*limit|heap.*size|max.*memory/i,\n },\n\n // Timeout rules\n {\n id: 'perf-050',\n name: 'Request Timeout',\n description: 'Request timeout values should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /(?:request|api|http).*timeout|timeout.*(?:second|ms)/i,\n },\n {\n id: 'perf-051',\n name: 'Timeout Match',\n description: 'Timeout values in docs should match implementation',\n severity: 'high',\n category: 'performance',\n check: (docs, code) => {\n // Extract timeout values\n const docsTimeout = docs.match(/timeout.*?(\\d+)\\s*(?:second|ms|minute)|(\\d+)\\s*(?:second|ms|minute).*timeout/gi) || [];\n const codeTimeout = code.match(/timeout.*?(\\d+)|(?:TIMEOUT|timeoutMs).*?(\\d+)/gi) || [];\n\n if (docsTimeout.length > 0 && codeTimeout.length > 0) {\n const docsNums = docsTimeout.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n const codeNums = codeTimeout.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n\n for (const num of docsNums) {\n if (!codeNums.includes(num)) return true;\n }\n }\n return false;\n },\n },\n\n // Async/Queue rules\n {\n id: 'perf-060',\n name: 'Queue Processing Time',\n description: 'Async queue processing times should be documented',\n severity: 'medium',\n category: 'performance',\n pattern: /queue.*(?:time|process|delay)|async.*(?:time|process)/i,\n },\n {\n id: 'perf-061',\n name: 'Retry Policy',\n description: 'Retry policies should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /retry.*(?:policy|count|interval|backoff)|exponential.*backoff/i,\n },\n\n // Concurrency rules\n {\n id: 'perf-070',\n name: 'Concurrent Request Limits',\n description: 'Concurrent request limits should be documented',\n severity: 'high',\n category: 'performance',\n pattern: /concurrent|parallel.*(?:request|connection)|max.*connection/i,\n },\n ];\n }\n\n getFocusCategories(): RequirementCategory[] {\n return ['performance', 'infrastructure'];\n }\n}\n","/**\n * Compliance Specialist Agent\n *\n * Focuses on compliance-related verification:\n * - GDPR data handling\n * - HIPAA requirements\n * - SOC2 controls\n * - Audit logging\n * - Data retention policies\n */\n\nimport {\n BaseSpecialistAgent,\n SpecialtyType,\n VerificationRule,\n} from './base-specialist.js';\nimport type { RequirementCategory } from '../types.js';\n\nexport class ComplianceAgent extends BaseSpecialistAgent {\n readonly specialty: SpecialtyType = 'compliance';\n\n getPromptContext(): string {\n return `You are a compliance specialist with expertise in:\n\n## GDPR (General Data Protection Regulation)\n- Lawful basis for data processing\n- Consent management and records\n- Data subject rights (access, rectification, erasure, portability)\n- Data Protection Impact Assessments (DPIA)\n- Data Processing Agreements (DPA)\n- Cross-border data transfers\n- Privacy by design and default\n- Breach notification requirements (72 hours)\n\n## HIPAA (Health Insurance Portability and Accountability Act)\n- Protected Health Information (PHI) handling\n- Minimum necessary principle\n- Business Associate Agreements (BAA)\n- Administrative, physical, and technical safeguards\n- Access controls and audit trails\n- Encryption requirements (at rest and in transit)\n- Incident response procedures\n\n## SOC 2 (Service Organization Control 2)\n- Trust Service Criteria:\n - Security (common criteria)\n - Availability\n - Processing Integrity\n - Confidentiality\n - Privacy\n- Access control policies\n- Change management procedures\n- Risk assessment processes\n- Vendor management\n\n## Audit Logging\n- What events to log (access, changes, deletions)\n- Log retention periods\n- Log integrity and tampering prevention\n- Log access controls\n- Searchability and retrieval\n\n## Data Retention\n- Retention period policies\n- Data deletion procedures\n- Archive strategies\n- Legal hold capabilities\n- Retention schedule documentation\n\n## Data Privacy\n- Personal data identification\n- Data classification\n- Anonymization/pseudonymization\n- Data minimization principles\n- Purpose limitation\n\nFocus on COMPLIANCE DRIFT where:\n- Documented privacy policies aren't implemented in code\n- Data retention periods don't match documentation\n- Audit logging requirements aren't met\n- Consent mechanisms differ from documentation\n- Security controls don't match compliance claims`;\n }\n\n getVerificationRules(): VerificationRule[] {\n return [\n // GDPR rules\n {\n id: 'comp-001',\n name: 'GDPR Consent Documentation',\n description: 'Consent collection and management should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /consent|gdpr|data.*protection|privacy.*policy/i,\n },\n {\n id: 'comp-002',\n name: 'Data Subject Rights',\n description: 'Data subject rights (access, deletion, portability) should be implemented',\n severity: 'critical',\n category: 'data',\n pattern: /(?:data|user).*(?:access|deletion|erasure|portability|export)|right.*to.*(?:be.*forgotten|erasure)/i,\n },\n {\n id: 'comp-003',\n name: 'Data Processing Basis',\n description: 'Legal basis for data processing should be documented',\n severity: 'high',\n category: 'data',\n pattern: /(?:lawful|legal).*basis|legitimate.*interest|contract.*necessity/i,\n },\n {\n id: 'comp-004',\n name: 'Cross-Border Transfers',\n description: 'Cross-border data transfer mechanisms should be documented',\n severity: 'high',\n category: 'data',\n pattern: /(?:cross.*border|international).*transfer|standard.*contractual.*clauses|adequacy.*decision/i,\n },\n {\n id: 'comp-005',\n name: 'Breach Notification',\n description: 'Data breach notification procedures should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /breach.*notif|72.*hour|data.*breach.*report/i,\n },\n\n // HIPAA rules\n {\n id: 'comp-010',\n name: 'PHI Handling',\n description: 'Protected Health Information handling should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /phi|protected.*health|hipaa|medical.*record/i,\n },\n {\n id: 'comp-011',\n name: 'BAA Requirements',\n description: 'Business Associate Agreements should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /business.*associate|baa|covered.*entity/i,\n },\n {\n id: 'comp-012',\n name: 'HIPAA Encryption',\n description: 'HIPAA encryption requirements should be met',\n severity: 'critical',\n category: 'data',\n check: (docs, code) => {\n const docsClaimsHIPAA = /hipaa.*compliant|phi.*encrypt/i.test(docs);\n const codeHasEncryption = /(?:aes|encrypt|cipher|crypto)/i.test(code);\n return docsClaimsHIPAA && !codeHasEncryption;\n },\n },\n {\n id: 'comp-013',\n name: 'Minimum Necessary',\n description: 'Minimum necessary principle should be implemented',\n severity: 'high',\n category: 'data',\n pattern: /minimum.*necessary|need.*to.*know|data.*minimization/i,\n },\n\n // SOC 2 rules\n {\n id: 'comp-020',\n name: 'SOC 2 Security Controls',\n description: 'SOC 2 security controls should be documented',\n severity: 'high',\n category: 'security',\n pattern: /soc.*2|trust.*service|security.*control/i,\n },\n {\n id: 'comp-021',\n name: 'Change Management',\n description: 'Change management procedures should be documented',\n severity: 'medium',\n category: 'security',\n pattern: /change.*management|change.*control|deployment.*process/i,\n },\n {\n id: 'comp-022',\n name: 'Access Control Policy',\n description: 'Access control policies should be documented and enforced',\n severity: 'high',\n category: 'security',\n pattern: /access.*control.*policy|principle.*least.*privilege|rbac.*policy/i,\n },\n {\n id: 'comp-023',\n name: 'Vendor Management',\n description: 'Third-party vendor management should be documented',\n severity: 'medium',\n category: 'security',\n pattern: /vendor.*management|third.*party.*risk|subprocessor/i,\n },\n\n // Audit logging rules\n {\n id: 'comp-030',\n name: 'Audit Log Events',\n description: 'Auditable events should be documented and logged',\n severity: 'critical',\n category: 'data',\n pattern: /audit.*log|audit.*trail|activity.*log/i,\n },\n {\n id: 'comp-031',\n name: 'Audit Log Implementation',\n description: 'Audit logging should be implemented as documented',\n severity: 'critical',\n category: 'data',\n check: (docs, code) => {\n const docsRequiresAudit = /audit.*log.*(?:all|every)|log.*(?:access|changes|deletion)/i.test(docs);\n const codeHasAuditLog = /(?:audit|log).*(?:event|action|activity)|\\.log\\(|logger\\./i.test(code);\n return docsRequiresAudit && !codeHasAuditLog;\n },\n },\n {\n id: 'comp-032',\n name: 'Log Retention Period',\n description: 'Audit log retention periods should be documented',\n severity: 'high',\n category: 'data',\n pattern: /log.*retention|retain.*log|(?:\\d+).*(?:day|month|year).*(?:log|audit)/i,\n },\n {\n id: 'comp-033',\n name: 'Log Integrity',\n description: 'Audit log integrity measures should be documented',\n severity: 'high',\n category: 'data',\n pattern: /log.*integrity|tamper.*proof|immutable.*log/i,\n },\n\n // Data retention rules\n {\n id: 'comp-040',\n name: 'Data Retention Policy',\n description: 'Data retention policies should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /data.*retention|retention.*(?:policy|period|schedule)/i,\n },\n {\n id: 'comp-041',\n name: 'Retention Period Match',\n description: 'Data retention periods should match between docs and code',\n severity: 'high',\n category: 'data',\n check: (docs, code) => {\n // Extract retention periods\n const docsRetention = docs.match(/(?:retain|keep|store).*?(\\d+)\\s*(?:day|month|year)|(\\d+)\\s*(?:day|month|year).*retention/gi) || [];\n const codeRetention = code.match(/(?:retention|ttl|expiry|delete.*after).*?(\\d+)|RETENTION.*?(\\d+)/gi) || [];\n\n if (docsRetention.length > 0 && codeRetention.length > 0) {\n const docsNums = docsRetention.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n const codeNums = codeRetention.map((l) => l.match(/\\d+/)?.[0]).filter(Boolean);\n\n for (const num of docsNums) {\n if (!codeNums.includes(num)) return true;\n }\n }\n return false;\n },\n },\n {\n id: 'comp-042',\n name: 'Data Deletion Procedures',\n description: 'Data deletion procedures should be documented',\n severity: 'high',\n category: 'data',\n pattern: /data.*deletion|delete.*(?:user|account|data)|purge.*data/i,\n },\n {\n id: 'comp-043',\n name: 'Legal Hold',\n description: 'Legal hold capabilities should be documented',\n severity: 'medium',\n category: 'data',\n pattern: /legal.*hold|litigation.*hold|preserve.*data/i,\n },\n\n // Privacy rules\n {\n id: 'comp-050',\n name: 'Personal Data Identification',\n description: 'Personal data fields should be identified and documented',\n severity: 'high',\n category: 'data',\n pattern: /personal.*data|pii|personally.*identifiable/i,\n },\n {\n id: 'comp-051',\n name: 'Data Classification',\n description: 'Data classification scheme should be documented',\n severity: 'medium',\n category: 'data',\n pattern: /data.*classif|(?:public|internal|confidential|restricted).*data/i,\n },\n {\n id: 'comp-052',\n name: 'Anonymization Implementation',\n description: 'Anonymization/pseudonymization should be implemented as documented',\n severity: 'high',\n category: 'data',\n check: (docs, code) => {\n const docsClaimsAnonymization = /anonymiz|pseudonymiz|de-identif/i.test(docs);\n const codeHasAnonymization = /(?:anonymize|hash|mask|redact|pseudonymize)/i.test(code);\n return docsClaimsAnonymization && !codeHasAnonymization;\n },\n },\n {\n id: 'comp-053',\n name: 'Cookie Consent',\n description: 'Cookie consent mechanisms should be documented',\n severity: 'high',\n category: 'data',\n pattern: /cookie.*consent|cookie.*banner|tracking.*consent/i,\n },\n\n // Encryption rules\n {\n id: 'comp-060',\n name: 'Encryption at Rest',\n description: 'Encryption at rest should be documented and implemented',\n severity: 'critical',\n category: 'data',\n pattern: /encrypt.*(?:at.*rest|stored|database)|(?:aes|kms).*(?:encrypt|key)/i,\n },\n {\n id: 'comp-061',\n name: 'Encryption in Transit',\n description: 'Encryption in transit should be documented',\n severity: 'critical',\n category: 'data',\n pattern: /encrypt.*(?:in.*transit|transport)|tls|https.*required/i,\n },\n {\n id: 'comp-062',\n name: 'Key Management',\n description: 'Encryption key management should be documented',\n severity: 'high',\n category: 'data',\n pattern: /key.*management|key.*rotation|kms|key.*(?:vault|storage)/i,\n },\n ];\n }\n\n getFocusCategories(): RequirementCategory[] {\n return ['data', 'security'];\n }\n}\n","/**\n * Specialist Agents Module\n *\n * Exports all specialist agents for domain-specific verification:\n * - SecurityAgent: Authentication, authorization, OWASP compliance\n * - APIContractAgent: Endpoints, schemas, rate limits\n * - PerformanceAgent: SLAs, caching, resource limits\n * - ComplianceAgent: GDPR, HIPAA, SOC2, audit logging\n */\n\nexport * from './base-specialist.js';\nexport * from './security-agent.js';\nexport * from './api-contract-agent.js';\nexport * from './performance-agent.js';\nexport * from './compliance-agent.js';\n\n// Re-export types\nexport type {\n SpecialtyType,\n VerificationRule,\n SpecialistFinding,\n SpecialistResult,\n SpecialistTaskInputs,\n} from './base-specialist.js';\n\n// Factory function to get all specialists\nimport { SecurityAgent } from './security-agent.js';\nimport { APIContractAgent } from './api-contract-agent.js';\nimport { PerformanceAgent } from './performance-agent.js';\nimport { ComplianceAgent } from './compliance-agent.js';\nimport type { BaseSpecialistAgent, SpecialtyType } from './base-specialist.js';\n\n/**\n * Create all specialist agents\n */\nexport function createAllSpecialists(): BaseSpecialistAgent[] {\n return [\n new SecurityAgent(),\n new APIContractAgent(),\n new PerformanceAgent(),\n new ComplianceAgent(),\n ];\n}\n\n/**\n * Create a specific specialist by type\n */\nexport function createSpecialist(specialty: SpecialtyType): BaseSpecialistAgent {\n switch (specialty) {\n case 'security':\n return new SecurityAgent();\n case 'api-contract':\n return new APIContractAgent();\n case 'performance':\n return new PerformanceAgent();\n case 'compliance':\n return new ComplianceAgent();\n default:\n throw new Error(`Unknown specialty: ${specialty}`);\n }\n}\n\n/**\n * Get available specialties\n */\nexport function getAvailableSpecialties(): SpecialtyType[] {\n return ['security', 'api-contract', 'performance', 'compliance'];\n}\n","/**\n * Orchestrator Agent\n *\n * The central coordinator for the VasperaPM multi-agent system.\n *\n * Responsibilities:\n * - Analyze project structure and determine verification strategy\n * - Create verification plans\n * - Allocate tasks to specialized agents\n * - Aggregate results and resolve conflicts\n * - Decide when to escalate to deeper analysis\n */\n\nimport { BaseAgent } from './base-agent.js';\nimport { DiscoveryAgent } from './discovery-agent.js';\nimport { AnalyzerAgent } from './analyzer-agent.js';\nimport { ValidatorAgent } from './validator-agent.js';\nimport {\n TaskMessage,\n ResultMessage,\n AgentContext,\n VerificationPlan,\n VerificationPhase,\n PlannedTask,\n VerifiedRequirement,\n ValidationResult,\n VerificationSummary,\n DiscoveredFile,\n DependencyGraph,\n DiscoverySummary,\n createTaskMessage,\n} from './types.js';\nimport {\n PreScreeningEngine,\n estimateTokenSavings,\n} from '../embeddings/index.js';\nimport {\n createAllSpecialists,\n getAvailableSpecialties,\n type BaseSpecialistAgent,\n type SpecialistResult,\n type SpecialtyType,\n} from './specialist/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface OrchestratorResult {\n plan: VerificationPlan;\n discovery: {\n docs: DiscoveredFile[];\n code: DiscoveredFile[];\n graph: DependencyGraph;\n summary: DiscoverySummary;\n };\n analysis: {\n requirements: VerifiedRequirement[];\n summary: VerificationSummary;\n disputes: VerifiedRequirement[];\n };\n specialistResults?: SpecialistResult[];\n tokensUsed: { input: number; output: number };\n tokensSaved?: number; // Tokens saved via AST and pre-screening\n preScreeningStats?: {\n originalTokens: number;\n screenedTokens: number;\n savedTokens: number;\n savingsPercent: number;\n };\n executionTime: number;\n phaseResults: Map<string, unknown>;\n}\n\nexport interface OrchestratorOptions {\n enableDebate?: boolean;\n enablePreScreening?: boolean; // Use embeddings to pre-screen content\n enableSpecialists?: boolean; // Run specialist agents for deeper analysis\n specialties?: SpecialtyType[]; // Which specialists to run (all if not specified)\n maxTokens?: number;\n verbose?: boolean;\n onProgress?: (phase: string, progress: number, message: string) => void;\n}\n\n// ============================================================================\n// Orchestrator Agent\n// ============================================================================\n\nexport class OrchestratorAgent extends BaseAgent {\n private discoveryAgent: DiscoveryAgent;\n private analyzerAgent: AnalyzerAgent;\n private validatorAgent: ValidatorAgent;\n private specialists: BaseSpecialistAgent[] = [];\n\n private options: OrchestratorOptions = {\n enableDebate: true,\n enablePreScreening: true, // Enable by default for cost savings\n enableSpecialists: false, // Disabled by default (opt-in for deeper analysis)\n maxTokens: 200000,\n verbose: false,\n };\n\n private preScreeningEngine: PreScreeningEngine | null = null;\n\n constructor() {\n super('orchestrator');\n this.discoveryAgent = new DiscoveryAgent();\n this.analyzerAgent = new AnalyzerAgent();\n this.validatorAgent = new ValidatorAgent();\n }\n\n async initialize(context: AgentContext): Promise<void> {\n await super.initialize(context);\n\n // Initialize child agents\n await Promise.all([\n this.discoveryAgent.initialize(context),\n this.analyzerAgent.initialize(context),\n this.validatorAgent.initialize(context),\n ]);\n\n this.emitEvent('agent:started', { agent: 'orchestrator', children: ['discovery', 'analyzer', 'validator'] });\n }\n\n /**\n * Initialize specialist agents based on options\n */\n private async initializeSpecialists(context: AgentContext): Promise<void> {\n const specialtiesToUse = this.options.specialties || getAvailableSpecialties();\n this.specialists = createAllSpecialists().filter((s) =>\n specialtiesToUse.includes(s.specialty)\n );\n\n await Promise.all(this.specialists.map((s) => s.initialize(context)));\n\n this.emitEvent('agent:started', {\n agent: 'specialists',\n specialties: this.specialists.map((s) => s.specialty),\n });\n }\n\n /**\n * Run specialist agents for domain-specific verification\n */\n private async runSpecialistVerification(\n docsContent: string,\n codeContent: string,\n existingFindings: VerifiedRequirement[]\n ): Promise<SpecialistResult[]> {\n if (this.specialists.length === 0) return [];\n\n const results: SpecialistResult[] = [];\n\n for (const specialist of this.specialists) {\n const task = createTaskMessage(\n 'orchestrator',\n 'specialist',\n 'specialist_verify',\n `Run ${specialist.specialty} specialist verification`,\n {\n docsContent,\n codeContent,\n existingFindings,\n }\n );\n\n const result = await specialist.execute(task);\n if (result.payload.success && result.payload.data) {\n results.push(result.payload.data as SpecialistResult);\n }\n }\n\n return results;\n }\n\n async execute(task: TaskMessage): Promise<ResultMessage> {\n const startTime = Date.now();\n this.status = 'executing';\n this.emitEvent('agent:task_started', { taskId: task.payload.taskId });\n\n try {\n const { taskType, inputs } = task.payload;\n let result: unknown;\n\n switch (taskType) {\n case 'full_verification':\n result = await this.runFullVerification(\n inputs.projectPath as string,\n inputs.options as OrchestratorOptions\n );\n break;\n case 'create_plan':\n result = await this.createPlan(inputs.projectPath as string);\n break;\n case 'execute_plan':\n result = await this.executePlan(inputs.plan as VerificationPlan);\n break;\n default:\n throw new Error(`Unknown task type: ${taskType}`);\n }\n\n const executionTime = Date.now() - startTime;\n this.tasksCompleted++;\n this.status = 'complete';\n this.emitEvent('agent:task_completed', { taskId: task.payload.taskId, success: true });\n\n const orchestratorResult = result as OrchestratorResult;\n return this.createSuccessResult(\n task.payload.taskId,\n result,\n orchestratorResult.analysis?.summary?.overallConfidence || 75,\n orchestratorResult.tokensUsed || { input: 0, output: 0 },\n executionTime\n );\n } catch (err) {\n const executionTime = Date.now() - startTime;\n const error = err instanceof Error ? err.message : 'Unknown error';\n this.status = 'error';\n\n return this.createErrorResult(task.payload.taskId, error, executionTime);\n }\n }\n\n /**\n * Run the complete verification pipeline\n */\n async runFullVerification(\n projectPath: string,\n options: OrchestratorOptions = {}\n ): Promise<OrchestratorResult> {\n this.options = { ...this.options, ...options };\n const startTime = Date.now();\n const phaseResults = new Map<string, unknown>();\n let totalTokens = { input: 0, output: 0 };\n\n // =========================================================================\n // Phase 1: Planning\n // =========================================================================\n this.progress('planning', 0, 'Analyzing project structure...');\n const plan = await this.createPlan(projectPath);\n this.emitEvent('orchestrator:plan_created', { plan });\n phaseResults.set('plan', plan);\n\n // =========================================================================\n // Phase 2: Discovery\n // =========================================================================\n this.progress('discovery', 10, 'Discovering documentation and code...');\n this.emitEvent('orchestrator:phase_started', { phase: 'discovery' });\n\n const discoveryTask = createTaskMessage(\n 'orchestrator',\n 'discovery',\n 'discover_all',\n 'Discover all docs and code files',\n {\n path: projectPath,\n options: { includeContent: true, maxFileSize: 512 * 1024 },\n }\n );\n\n const discoveryResult = await this.discoveryAgent.execute(discoveryTask);\n if (!discoveryResult.payload.success) {\n throw new Error(`Discovery failed: ${discoveryResult.payload.errors?.join(', ')}`);\n }\n\n const discovery = discoveryResult.payload.data as {\n docs: DiscoveredFile[];\n code: DiscoveredFile[];\n graph: DependencyGraph;\n summary: DiscoverySummary;\n };\n phaseResults.set('discovery', discovery);\n this.emitEvent('orchestrator:phase_completed', { phase: 'discovery', result: discovery.summary });\n\n this.progress('discovery', 25, `Found ${discovery.summary.totalDocs} docs, ${discovery.summary.totalCode} code files`);\n\n // Set framework context on validator for pattern-enhanced validation\n this.validatorAgent.setFrameworkContext(\n discovery.summary.frameworks,\n Object.keys(discovery.summary.codeByLanguage)\n );\n\n // =========================================================================\n // Phase 3: Content Extraction (with optional pre-screening)\n // =========================================================================\n this.progress('extraction', 30, 'Extracting content for analysis...');\n\n let docsContent = this.extractDocsContent(discovery.docs);\n let codeContent = this.extractCodeContent(discovery.code);\n let preScreeningStats: OrchestratorResult['preScreeningStats'] | undefined;\n\n if (!docsContent || docsContent.length < 100) {\n throw new Error('No documentation content found');\n }\n if (!codeContent || codeContent.length < 100) {\n throw new Error('No code content found');\n }\n\n // Apply pre-screening if enabled (reduces token usage by 50-70%)\n if (this.options.enablePreScreening) {\n this.progress('extraction', 32, 'Pre-screening content with embeddings...');\n\n this.preScreeningEngine = new PreScreeningEngine();\n\n // Build index from all docs and code\n const docsForIndex = discovery.docs\n .filter((d) => d.content)\n .map((d) => ({\n content: d.content!,\n path: d.relativePath,\n category: d.category,\n }));\n\n const codeForIndex = discovery.code\n .filter((c) => c.content)\n .map((c) => ({\n content: c.content!,\n path: c.relativePath,\n language: c.language,\n category: c.category,\n }));\n\n this.preScreeningEngine.buildIndex(docsForIndex, codeForIndex);\n\n // Pre-screen for requirements-related content\n const screened = this.preScreeningEngine.preScreenForRequirements(\n docsContent,\n codeContent,\n discovery.summary.frameworks[0]\n );\n\n // Calculate savings\n preScreeningStats = estimateTokenSavings(\n docsContent,\n codeContent,\n screened.docs,\n screened.code\n );\n\n // Use pre-screened content if we got good results\n if (screened.docs.length > 100 && screened.code.length > 100) {\n docsContent = screened.docs;\n codeContent = screened.code;\n\n this.progress(\n 'extraction',\n 35,\n `Pre-screening saved ${preScreeningStats.savingsPercent}% tokens (${preScreeningStats.savedTokens} tokens)`\n );\n this.emitEvent('orchestrator:pre_screening', preScreeningStats);\n } else {\n this.progress('extraction', 35, 'Pre-screening skipped (insufficient results)');\n preScreeningStats = undefined;\n }\n }\n\n // =========================================================================\n // Phase 4: Analysis (with AST optimization)\n // =========================================================================\n this.progress('analysis', 40, 'Analyzing requirements and features...');\n this.emitEvent('orchestrator:phase_started', { phase: 'analysis' });\n\n // Prepare code files for AST-based analysis (reduces token usage)\n const codeFiles = this.prepareCodeFilesForAST(discovery.code);\n const useAstMode = codeFiles.length > 0;\n\n if (useAstMode) {\n this.progress('analysis', 42, `Using AST optimization for ${codeFiles.length} code files`);\n }\n\n const analysisTask = createTaskMessage(\n 'orchestrator',\n 'analyzer',\n 'analyze_full',\n 'Extract requirements and features, map them together',\n {\n docsContent,\n codeContent,\n framework: discovery.summary.frameworks[0], // Primary framework\n codeFiles: useAstMode ? codeFiles : undefined,\n }\n );\n\n const analysisResult = await this.analyzerAgent.execute(analysisTask);\n if (!analysisResult.payload.success) {\n throw new Error(`Analysis failed: ${analysisResult.payload.errors?.join(', ')}`);\n }\n\n const analysis = analysisResult.payload.data as {\n requirements: unknown[];\n mappings: unknown[];\n confidence: number;\n tokensUsed: { input: number; output: number };\n tokensSaved?: number;\n };\n totalTokens.input += analysis.tokensUsed?.input || 0;\n totalTokens.output += analysis.tokensUsed?.output || 0;\n const tokensSaved = analysis.tokensSaved || 0;\n phaseResults.set('analysis', analysis);\n this.emitEvent('orchestrator:phase_completed', { phase: 'analysis', tokensSaved });\n\n const savedMsg = tokensSaved > 0 ? ` (saved ~${tokensSaved} tokens via AST)` : '';\n this.progress('analysis', 60, `Found ${analysis.requirements.length} requirements${savedMsg}`);\n\n // =========================================================================\n // Phase 5: Validation\n // =========================================================================\n this.progress('validation', 65, 'Cross-validating requirements against code...');\n this.emitEvent('orchestrator:phase_started', { phase: 'validation' });\n\n // Split requirements by source\n const docReqs = (analysis.requirements as Array<{ source: string }>).filter((r) => r.source === 'docs');\n const codeFeats = (analysis.requirements as Array<{ source: string }>).filter((r) => r.source === 'code');\n\n const validationTask = createTaskMessage(\n 'orchestrator',\n 'validator',\n 'validate',\n 'Cross-validate and score findings',\n {\n docRequirements: docReqs,\n codeFeatures: codeFeats,\n mappings: analysis.mappings,\n docsContent,\n codeContent,\n enableDebate: this.options.enableDebate,\n }\n );\n\n const validationResult = await this.validatorAgent.execute(validationTask);\n if (!validationResult.payload.success) {\n throw new Error(`Validation failed: ${validationResult.payload.errors?.join(', ')}`);\n }\n\n const validation = validationResult.payload.data as ValidationResult & {\n tokensUsed: { input: number; output: number };\n };\n totalTokens.input += validation.tokensUsed?.input || 0;\n totalTokens.output += validation.tokensUsed?.output || 0;\n phaseResults.set('validation', validation);\n this.emitEvent('orchestrator:phase_completed', { phase: 'validation', result: validation.summary });\n\n this.progress('validation', 85, `Verified ${validation.summary.verified} requirements`);\n\n // =========================================================================\n // Phase 6: Specialist Verification (Optional)\n // =========================================================================\n let specialistResults: SpecialistResult[] = [];\n\n if (this.options.enableSpecialists) {\n this.progress('specialists', 87, 'Initializing specialist agents...');\n this.emitEvent('orchestrator:phase_started', { phase: 'specialists' });\n\n // Initialize specialists if not already done\n if (this.specialists.length === 0 && this.context) {\n await this.initializeSpecialists(this.context);\n }\n\n this.progress('specialists', 88, `Running ${this.specialists.length} specialist agents...`);\n\n specialistResults = await this.runSpecialistVerification(\n docsContent,\n codeContent,\n validation.verified\n );\n\n // Aggregate specialist tokens\n for (const specResult of specialistResults) {\n totalTokens.input += specResult.tokensUsed.input;\n totalTokens.output += specResult.tokensUsed.output;\n }\n\n phaseResults.set('specialists', specialistResults);\n\n const totalSpecialistIssues = specialistResults.reduce(\n (sum, r) => sum + r.summary.issues,\n 0\n );\n this.emitEvent('orchestrator:phase_completed', {\n phase: 'specialists',\n specialties: specialistResults.map((r) => r.specialty),\n totalIssues: totalSpecialistIssues,\n });\n\n this.progress(\n 'specialists',\n 92,\n `Specialist analysis complete: ${totalSpecialistIssues} additional issues found`\n );\n }\n\n // =========================================================================\n // Phase 7: Aggregation\n // =========================================================================\n this.progress('aggregation', 95, 'Aggregating results...');\n\n const executionTime = Date.now() - startTime;\n\n // Calculate total tokens saved (AST + pre-screening)\n const totalTokensSaved = tokensSaved + (preScreeningStats?.savedTokens || 0);\n\n const orchestratorResult: OrchestratorResult = {\n plan,\n discovery,\n analysis: {\n requirements: validation.verified,\n summary: validation.summary,\n disputes: validation.disputes,\n },\n specialistResults: specialistResults.length > 0 ? specialistResults : undefined,\n tokensUsed: totalTokens,\n tokensSaved: totalTokensSaved,\n preScreeningStats,\n executionTime,\n phaseResults,\n };\n\n this.emitEvent('orchestrator:analysis_complete', {\n summary: validation.summary,\n executionTime,\n tokensUsed: totalTokens,\n });\n\n this.progress('complete', 100, 'Verification complete');\n\n return orchestratorResult;\n }\n\n /**\n * Create a verification plan for a project\n */\n async createPlan(projectPath: string): Promise<VerificationPlan> {\n this.status = 'planning';\n\n const phases: VerificationPhase[] = [\n {\n id: 'phase-discovery',\n name: 'Discovery',\n description: 'Find and categorize all documentation and code files',\n agent: 'discovery',\n dependencies: [],\n tasks: [\n {\n id: 'task-discover-docs',\n type: 'discover_docs',\n description: 'Find all documentation files',\n inputs: { path: projectPath },\n estimatedTokens: 0,\n priority: 'high',\n },\n {\n id: 'task-discover-code',\n type: 'discover_code',\n description: 'Find all code files',\n inputs: { path: projectPath },\n estimatedTokens: 0,\n priority: 'high',\n },\n {\n id: 'task-build-graph',\n type: 'build_graph',\n description: 'Build dependency graph',\n inputs: {},\n estimatedTokens: 0,\n priority: 'medium',\n },\n ],\n status: 'pending',\n },\n {\n id: 'phase-analysis',\n name: 'Analysis',\n description: 'Extract requirements and features, map them together',\n agent: 'analyzer',\n dependencies: ['phase-discovery'],\n tasks: [\n {\n id: 'task-extract-reqs',\n type: 'extract_requirements',\n description: 'Extract requirements from documentation',\n inputs: {},\n estimatedTokens: 20000,\n priority: 'high',\n },\n {\n id: 'task-extract-feats',\n type: 'extract_features',\n description: 'Extract features from code',\n inputs: {},\n estimatedTokens: 25000,\n priority: 'high',\n },\n {\n id: 'task-map',\n type: 'map_requirements',\n description: 'Map requirements to features',\n inputs: {},\n estimatedTokens: 15000,\n priority: 'high',\n },\n ],\n status: 'pending',\n },\n {\n id: 'phase-validation',\n name: 'Validation',\n description: 'Cross-validate and debate findings',\n agent: 'validator',\n dependencies: ['phase-analysis'],\n tasks: [\n {\n id: 'task-cross-validate',\n type: 'validate',\n description: 'Cross-validate requirements against code',\n inputs: {},\n estimatedTokens: 30000,\n priority: 'critical',\n },\n {\n id: 'task-debate',\n type: 'debate',\n description: 'Debate low-confidence findings',\n inputs: {},\n estimatedTokens: 20000,\n priority: 'medium',\n },\n ],\n status: 'pending',\n },\n ];\n\n const plan: VerificationPlan = {\n id: `plan_${Date.now()}`,\n projectPath,\n createdAt: new Date().toISOString(),\n phases,\n estimatedTokens: phases.reduce(\n (sum, p) => sum + p.tasks.reduce((tsum, t) => tsum + t.estimatedTokens, 0),\n 0\n ),\n estimatedTime: 60000, // ~1 minute estimate\n };\n\n return plan;\n }\n\n /**\n * Execute a verification plan\n */\n async executePlan(plan: VerificationPlan): Promise<OrchestratorResult> {\n return this.runFullVerification(plan.projectPath, this.options);\n }\n\n // =========================================================================\n // Helper Methods\n // =========================================================================\n\n private progress(phase: string, percent: number, message: string): void {\n if (this.options.onProgress) {\n this.options.onProgress(phase, percent, message);\n }\n if (this.options.verbose) {\n console.log(`[${phase}] ${percent}% - ${message}`);\n }\n }\n\n private extractDocsContent(docs: DiscoveredFile[], maxSize = 100000): string {\n let totalSize = 0;\n const contents: string[] = [];\n\n // Sort by category importance\n const sortOrder = ['readme', 'prd', 'api', 'architecture', 'other', 'changelog', 'contributing'];\n const sorted = [...docs].sort((a, b) => {\n const aIdx = sortOrder.indexOf(a.category);\n const bIdx = sortOrder.indexOf(b.category);\n return (aIdx === -1 ? 999 : aIdx) - (bIdx === -1 ? 999 : bIdx);\n });\n\n for (const doc of sorted) {\n if (totalSize >= maxSize) break;\n if (!doc.content) continue;\n\n const header = `\\n\\n---\\n## File: ${doc.relativePath}\\n---\\n\\n`;\n const toAdd = header + doc.content;\n\n if (totalSize + toAdd.length <= maxSize) {\n contents.push(toAdd);\n totalSize += toAdd.length;\n }\n }\n\n return contents.join('');\n }\n\n private extractCodeContent(code: DiscoveredFile[], maxSize = 100000): string {\n let totalSize = 0;\n const contents: string[] = [];\n\n // Filter to important files\n const important = code.filter((c) =>\n ['routes', 'types', 'utils', 'components'].includes(c.category)\n );\n\n for (const file of important) {\n if (totalSize >= maxSize) break;\n if (!file.content) continue;\n\n const header = `\\n\\n---\\n## File: ${file.relativePath} (${file.language})\\n---\\n\\n`;\n const toAdd = header + file.content;\n\n if (totalSize + toAdd.length <= maxSize) {\n contents.push(toAdd);\n totalSize += toAdd.length;\n }\n }\n\n return contents.join('');\n }\n\n /**\n * Prepare code files for AST-based analysis\n * Filters to TypeScript/JavaScript files that can be parsed\n */\n private prepareCodeFilesForAST(\n code: DiscoveredFile[]\n ): Array<{ content: string; path: string; relativePath: string }> {\n // Only TypeScript/JavaScript files can be parsed with our current AST module\n const parsableLanguages = ['typescript', 'javascript'];\n\n // Filter to important categories that benefit from AST analysis\n const importantCategories = ['routes', 'types', 'utils', 'components', 'config'];\n\n const astFiles: Array<{ content: string; path: string; relativePath: string }> = [];\n let totalSize = 0;\n const maxTotalSize = 500000; // 500KB limit for AST processing\n\n // Sort by importance: routes and types first\n const sorted = [...code].sort((a, b) => {\n const priorityOrder = ['routes', 'types', 'config', 'components', 'utils', 'other'];\n const aIdx = priorityOrder.indexOf(a.category);\n const bIdx = priorityOrder.indexOf(b.category);\n return (aIdx === -1 ? 999 : aIdx) - (bIdx === -1 ? 999 : bIdx);\n });\n\n for (const file of sorted) {\n // Skip if not parsable\n if (!file.language || !parsableLanguages.includes(file.language)) continue;\n if (!file.content) continue;\n\n // Skip test files for AST analysis (focus on production code)\n if (file.category === 'tests') continue;\n\n // Prefer important categories\n if (!importantCategories.includes(file.category)) continue;\n\n // Size limit per file\n if (file.content.length > 100000) continue; // Skip very large files\n\n // Total size limit\n if (totalSize + file.content.length > maxTotalSize) break;\n\n astFiles.push({\n content: file.content,\n path: file.path,\n relativePath: file.relativePath,\n });\n totalSize += file.content.length;\n }\n\n return astFiles;\n }\n\n /**\n * Get aggregated state of all agents\n */\n getSystemState(): {\n orchestrator: ReturnType<BaseAgent['getState']>;\n discovery: ReturnType<BaseAgent['getState']>;\n analyzer: ReturnType<BaseAgent['getState']>;\n validator: ReturnType<BaseAgent['getState']>;\n } {\n return {\n orchestrator: this.getState(),\n discovery: this.discoveryAgent.getState(),\n analyzer: this.analyzerAgent.getState(),\n validator: this.validatorAgent.getState(),\n };\n }\n\n async shutdown(): Promise<void> {\n const shutdownTasks = [\n this.discoveryAgent.shutdown(),\n this.analyzerAgent.shutdown(),\n this.validatorAgent.shutdown(),\n ...this.specialists.map((s) => s.shutdown()),\n super.shutdown(),\n ];\n await Promise.all(shutdownTasks);\n }\n}\n","/**\n * VasperaPM Multi-Agent System\n *\n * Exports all agents and provides a unified interface for running\n * the multi-agent verification pipeline.\n */\n\nexport * from './types.js';\nexport * from './base-agent.js';\nexport * from './discovery-agent.js';\nexport * from './analyzer-agent.js';\nexport * from './validator-agent.js';\nexport * from './orchestrator-agent.js';\nexport * from './specialist/index.js';\n\nimport { OrchestratorAgent, OrchestratorResult, OrchestratorOptions } from './orchestrator-agent.js';\nimport { AgentContext, AgentConfig, AgentMemory } from './types.js';\n\n// ============================================================================\n// Unified Interface\n// ============================================================================\n\n/**\n * Run the multi-agent verification pipeline\n *\n * This is the main entry point for running verification using the\n * coordinated multi-agent system.\n */\nexport async function runAgentVerification(\n projectPath: string,\n outputPath: string,\n options: OrchestratorOptions = {}\n): Promise<OrchestratorResult> {\n // Create default config\n const config: AgentConfig = {\n maxTokensPerCall: 50000,\n maxRetries: 3,\n debateEnabled: options.enableDebate ?? true,\n confidenceThreshold: 70,\n model: 'balanced',\n };\n\n // Create memory (will be enhanced with VasperaMemory integration later)\n const memory: AgentMemory = {\n previousFindings: new Map(),\n patterns: new Map(),\n frameworkRules: new Map(),\n };\n\n // Create context\n const context: AgentContext = {\n projectPath,\n outputPath,\n config,\n memory,\n };\n\n // Create and initialize orchestrator\n const orchestrator = new OrchestratorAgent();\n await orchestrator.initialize(context);\n\n try {\n // Run full verification\n const result = await orchestrator.runFullVerification(projectPath, options);\n return result;\n } finally {\n await orchestrator.shutdown();\n }\n}\n\n/**\n * Create an orchestrator instance for more control\n */\nexport function createOrchestrator(): OrchestratorAgent {\n return new OrchestratorAgent();\n}\n","/**\n * verify_docs_code Tool\n *\n * MCP tool that exposes the multi-agent verification pipeline.\n * Verifies documentation against code implementation to detect drift.\n *\n * This tool wires the agents/orchestrator to the MCP server,\n * enabling users to run full doc-code verification through Claude.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, jsonResult, errorResult } from './types.js';\nimport { runAgentVerification, OrchestratorResult } from '../agents/index.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync } from 'fs';\nimport { resolve } from 'path';\n\n/**\n * Format the orchestrator result as a human-readable markdown report\n */\nfunction formatVerificationReport(result: OrchestratorResult): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# Documentation-Code Verification Report');\n lines.push('');\n lines.push(`**Generated:** ${new Date().toISOString()}`);\n lines.push(`**Execution Time:** ${result.executionTime}ms`);\n lines.push('');\n\n // Summary\n const summary = result.analysis?.summary;\n if (summary) {\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Total Requirements | ${summary.total} |`);\n lines.push(`| Verified | ${summary.verified} |`);\n lines.push(`| Drift Detected | ${summary.drift} |`);\n lines.push(`| Undocumented | ${summary.undocumented} |`);\n lines.push(`| Unimplemented | ${summary.unimplemented} |`);\n lines.push(`| Overall Confidence | ${summary.overallConfidence}% |`);\n lines.push('');\n\n // Status indicator\n if (summary.drift === 0 && summary.unimplemented === 0) {\n lines.push('**Status:** ✅ All documentation verified against code');\n } else if (summary.drift > 0) {\n lines.push(`**Status:** ⚠️ ${summary.drift} drift issue(s) detected`);\n } else {\n lines.push(`**Status:** 📝 ${summary.unimplemented} unimplemented requirement(s)`);\n }\n lines.push('');\n }\n\n // Discovery summary\n const discovery = result.discovery?.summary;\n if (discovery) {\n lines.push('## Discovery');\n lines.push('');\n lines.push(`- **Documentation Files:** ${discovery.totalDocs}`);\n lines.push(`- **Code Files:** ${discovery.totalCode}`);\n if (discovery.frameworks?.length > 0) {\n lines.push(`- **Frameworks Detected:** ${discovery.frameworks.join(', ')}`);\n }\n lines.push('');\n }\n\n // Pre-screening savings\n if (result.preScreeningStats) {\n lines.push('## Token Optimization');\n lines.push('');\n lines.push(`- **Original Tokens:** ${result.preScreeningStats.originalTokens.toLocaleString()}`);\n lines.push(`- **After Pre-screening:** ${result.preScreeningStats.screenedTokens.toLocaleString()}`);\n lines.push(`- **Tokens Saved:** ${result.preScreeningStats.savedTokens.toLocaleString()} (${result.preScreeningStats.savingsPercent}%)`);\n lines.push('');\n }\n\n // Requirements breakdown\n const requirements = result.analysis?.requirements || [];\n if (requirements.length > 0) {\n // Critical drift\n const criticalDrift = requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity === 'critical'\n );\n if (criticalDrift.length > 0) {\n lines.push('## 🚨 Critical Drift');\n lines.push('');\n for (const req of criticalDrift) {\n const id = req.requirement?.id || 'Unknown';\n const desc = req.requirement?.description || req.documentedBehavior || 'No description';\n lines.push(`### ${id}`);\n lines.push(`**Description:** ${desc}`);\n if (req.documentedBehavior) lines.push(`**Documented:** ${req.documentedBehavior}`);\n if (req.implementedBehavior) lines.push(`**Implemented:** ${req.implementedBehavior}`);\n if (req.drift?.description) lines.push(`**Issue:** ${req.drift.description}`);\n if (req.drift?.recommendation) lines.push(`**Recommendation:** ${req.drift.recommendation.replace(/_/g, ' ')}`);\n lines.push('');\n }\n }\n\n // High/Medium drift\n const otherDrift = requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity !== 'critical'\n );\n if (otherDrift.length > 0) {\n lines.push('## ⚠️ Drift Detected');\n lines.push('');\n for (const req of otherDrift) {\n const id = req.requirement?.id || 'Unknown';\n const desc = req.drift?.description || req.requirement?.description || 'No description';\n lines.push(`- **${id}** (${req.drift?.severity || 'medium'}): ${desc}`);\n }\n lines.push('');\n }\n\n // Verified\n const verified = requirements.filter((r) => r.status === 'verified');\n if (verified.length > 0) {\n lines.push('## ✅ Verified Requirements');\n lines.push('');\n for (const req of verified) {\n const id = req.requirement?.id || 'Unknown';\n const desc = req.requirement?.description || 'No description';\n lines.push(`- **${id}:** ${desc} (${req.confidence}% confidence)`);\n }\n lines.push('');\n }\n\n // Undocumented\n const undocumented = requirements.filter((r) => r.status === 'undocumented');\n if (undocumented.length > 0) {\n lines.push('## ❌ Undocumented Features');\n lines.push('');\n lines.push('These features exist in code but are not documented:');\n lines.push('');\n for (const req of undocumented) {\n const desc = req.implementedBehavior || req.requirement?.description || 'No description';\n lines.push(`- ${desc}`);\n }\n lines.push('');\n }\n\n // Unimplemented\n const unimplemented = requirements.filter((r) => r.status === 'unimplemented');\n if (unimplemented.length > 0) {\n lines.push('## 🔴 Unimplemented Requirements');\n lines.push('');\n lines.push('These requirements are documented but not implemented:');\n lines.push('');\n for (const req of unimplemented) {\n const id = req.requirement?.id || 'Unknown';\n const desc = req.documentedBehavior || req.requirement?.description || 'No description';\n lines.push(`- **${id}:** ${desc}`);\n }\n lines.push('');\n }\n }\n\n // Disputes (if debate was enabled)\n const disputes = result.analysis?.disputes || [];\n if (disputes.length > 0) {\n lines.push('## 🔍 Items Requiring Review');\n lines.push('');\n lines.push('These items had low confidence or disagreement between agents:');\n lines.push('');\n for (const req of disputes) {\n const id = req.requirement?.id || 'Unknown';\n const desc = req.requirement?.description || 'No description';\n lines.push(`- **${id}:** ${desc} (${req.confidence}% confidence)`);\n }\n lines.push('');\n }\n\n // Tokens used\n lines.push('## Resource Usage');\n lines.push('');\n lines.push(`- **Input Tokens:** ${result.tokensUsed?.input?.toLocaleString() || 0}`);\n lines.push(`- **Output Tokens:** ${result.tokensUsed?.output?.toLocaleString() || 0}`);\n if (result.tokensSaved) {\n lines.push(`- **Tokens Saved (AST):** ${result.tokensSaved.toLocaleString()}`);\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * verify_docs_code MCP Tool Definition\n */\nexport const verifyDocsCodeTool: ToolDefinition = {\n tool: {\n name: 'verify_docs_code',\n description: `Verify documentation against code implementation to detect drift.\n\nUses a multi-agent system to:\n1. Discover all documentation and code files\n2. Extract requirements from docs and features from code\n3. Cross-validate to detect drift, undocumented features, and unimplemented requirements\n4. Optionally debate findings for higher accuracy\n\nReturns a comprehensive verification report with:\n- Summary statistics\n- Critical drift items requiring immediate attention\n- All verified, drifted, undocumented, and unimplemented items\n- Confidence scores and recommendations\n\nBest for: Ensuring documentation stays in sync with code implementation.`,\n inputSchema: {\n type: 'object',\n properties: {\n repoPath: {\n type: 'string',\n description: 'Path to the repository to verify (absolute or relative)',\n },\n framework: {\n type: 'string',\n enum: ['nextjs', 'express', 'django', 'fastapi', 'spring-boot', 'generic'],\n default: 'generic',\n description: 'Framework hint for better analysis (auto-detected if not specified)',\n },\n strictness: {\n type: 'string',\n enum: ['lenient', 'standard', 'strict'],\n default: 'standard',\n description: 'Verification strictness level',\n },\n enableDebate: {\n type: 'boolean',\n default: true,\n description: 'Enable agent debate for higher accuracy (slower but more accurate)',\n },\n enablePreScreening: {\n type: 'boolean',\n default: true,\n description: 'Enable embeddings pre-screening for token savings',\n },\n outputFormat: {\n type: 'string',\n enum: ['markdown', 'json'],\n default: 'markdown',\n description: 'Output format for the verification report',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to repoPath)',\n },\n },\n required: ['repoPath'],\n },\n } as Tool,\n\n handler: async (args, _validation) => {\n const repoPath = args.repoPath as string;\n const strictness = (args.strictness as string) || 'standard';\n const enableDebate = args.enableDebate !== false; // Default true\n const enablePreScreening = args.enablePreScreening !== false; // Default true\n const outputFormat = (args.outputFormat as string) || 'markdown';\n const projectRoot = (args.projectRoot as string) || repoPath;\n\n // Validate repo path exists\n const resolvedPath = resolve(repoPath);\n if (!existsSync(resolvedPath)) {\n return errorResult(`Repository path does not exist: ${resolvedPath}`);\n }\n\n try {\n // Run the multi-agent verification pipeline\n const result = await runAgentVerification(resolvedPath, '.vaspera-output', {\n enableDebate: strictness === 'strict' || enableDebate,\n enablePreScreening,\n verbose: false,\n });\n\n // Calculate total tokens\n const totalTokens = (result.tokensUsed?.input || 0) + (result.tokensUsed?.output || 0);\n\n // Format output\n let output: string;\n if (outputFormat === 'json') {\n output = JSON.stringify(result, null, 2);\n } else {\n output = formatVerificationReport(result);\n }\n\n // Save to project's vasperaPM folder\n const defaults = getToolDefaults('verify_docs_code');\n const saved = saveToolOutput({\n projectRoot: resolve(projectRoot),\n toolName: 'verify_docs_code',\n category: defaults.category,\n filename: defaults.filename,\n content: output,\n format: outputFormat === 'json' ? 'json' : 'md',\n inputs: [resolvedPath],\n tokensUsed: totalTokens,\n });\n\n if (outputFormat === 'json') {\n return jsonResult(result, totalTokens);\n }\n\n return markdownResult(output + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Verification failed: ${message}`);\n }\n },\n\n requiredScope: 'tools:verify_docs_code',\n};\n","/**\n * VasperaBench - Benchmark Types\n *\n * Types and interfaces for the VasperaBench doc-code drift detection benchmark.\n * Establishes the standard format for benchmark samples, predictions, and evaluation metrics.\n */\n\n// ============================================================================\n// Sample Types\n// ============================================================================\n\nexport type DriftStatus = 'verified' | 'drift' | 'undocumented' | 'unimplemented';\n\nexport type DriftSeverity = 'critical' | 'high' | 'medium' | 'low';\n\nexport type DriftType =\n | 'value_mismatch' // Values differ (e.g., rate limits, timeouts)\n | 'signature_change' // API signature changed\n | 'behavior_change' // Implementation behavior differs from docs\n | 'missing_parameter' // Doc mentions param not in code\n | 'extra_parameter' // Code has param not in docs\n | 'type_mismatch' // Type differs between doc and code\n | 'deprecation_drift' // Deprecated item handling mismatch\n | 'security_change' // Security-related drift\n | 'config_mismatch'; // Configuration value mismatch\n\nexport type DriftRecommendation = 'update_docs' | 'update_code' | 'needs_discussion';\n\nexport type Framework =\n | 'nextjs'\n | 'express'\n | 'django'\n | 'spring-boot'\n | 'fastapi'\n | 'rails'\n | 'laravel'\n | 'generic';\n\nexport type BenchmarkCategory =\n | 'api-contracts'\n | 'rate-limits'\n | 'auth-flows'\n | 'config-values'\n | 'error-handling'\n | 'data-models'\n | 'security'\n | 'performance';\n\nexport type DifficultyLevel = 'easy' | 'medium' | 'hard' | 'expert';\n\n// ============================================================================\n// Sample Format\n// ============================================================================\n\nexport interface DocumentationContent {\n /** The documentation content (markdown/text) */\n content: string;\n /** Source file path */\n source: string;\n /** Section name within the documentation */\n section: string;\n /** Line number range if applicable */\n lineRange?: { start: number; end: number };\n}\n\nexport interface CodeContent {\n /** The code content */\n content: string;\n /** Source file path */\n file: string;\n /** Programming language */\n language: string;\n /** Line number range */\n lineRange?: { start: number; end: number };\n /** Relevant function/class name */\n symbol?: string;\n}\n\nexport interface GroundTruthLabel {\n /** The verification status */\n status: DriftStatus;\n /** Severity level for drift */\n severity?: DriftSeverity;\n /** Type of drift detected */\n driftType?: DriftType;\n /** Human explanation of the drift */\n explanation: string;\n /** Recommended action */\n recommendation?: DriftRecommendation;\n /** Key evidence points */\n keyEvidence?: string[];\n}\n\nexport interface SampleMetadata {\n /** Contributor ID */\n contributor: string;\n /** Whether the sample has been verified by multiple reviewers */\n verified: boolean;\n /** Date added to benchmark */\n added: string;\n /** Version of the benchmark format */\n version: string;\n /** Additional tags */\n tags?: string[];\n /** Notes from reviewers */\n reviewerNotes?: string;\n}\n\nexport interface BenchmarkSample {\n /** Unique identifier */\n id: string;\n /** Category of drift */\n category: BenchmarkCategory;\n /** Framework context */\n framework: Framework;\n /** Difficulty level */\n difficulty: DifficultyLevel;\n /** Documentation content */\n documentation: DocumentationContent;\n /** Code content */\n code: CodeContent;\n /** Ground truth label */\n label: GroundTruthLabel;\n /** Sample metadata */\n metadata: SampleMetadata;\n}\n\n// ============================================================================\n// Prediction Types\n// ============================================================================\n\nexport interface SystemPrediction {\n /** Sample ID being predicted */\n sampleId: string;\n /** Predicted status */\n predictedStatus: DriftStatus;\n /** Confidence score (0-1) */\n confidence: number;\n /** Predicted severity (if drift) */\n predictedSeverity?: DriftSeverity;\n /** Predicted drift type (if drift) */\n predictedDriftType?: DriftType;\n /** System's reasoning */\n reasoning?: string;\n /** Token usage for this prediction */\n tokensUsed?: { input: number; output: number };\n /** Latency in milliseconds */\n latencyMs?: number;\n}\n\nexport interface SystemSubmission {\n /** System name */\n systemName: string;\n /** System version */\n version: string;\n /** Submission date */\n submittedAt: string;\n /** Model used (if applicable) */\n model?: string;\n /** Predictions for all samples */\n predictions: SystemPrediction[];\n /** Optional metadata */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Evaluation Metrics\n// ============================================================================\n\nexport interface ConfusionMatrix {\n /** True positives (correctly identified drift) */\n truePositives: number;\n /** True negatives (correctly identified verified) */\n trueNegatives: number;\n /** False positives (incorrectly flagged as drift) */\n falsePositives: number;\n /** False negatives (missed drift) */\n falseNegatives: number;\n}\n\nexport interface ClassificationMetrics {\n /** Overall accuracy */\n accuracy: number;\n /** Precision (true drift / predicted drift) */\n precision: number;\n /** Recall (true drift / actual drift) */\n recall: number;\n /** F1 score (harmonic mean of precision and recall) */\n f1: number;\n /** Matthews Correlation Coefficient */\n mcc?: number;\n}\n\nexport interface SeverityMetrics {\n /** Accuracy when drift is detected and severity is predicted */\n severityAccuracy: number;\n /** Breakdown by severity level */\n bySeverity: Record<DriftSeverity, ClassificationMetrics>;\n}\n\nexport interface CategoryMetrics {\n /** Accuracy of drift type classification */\n categoryAccuracy: number;\n /** Breakdown by category */\n byCategory: Record<BenchmarkCategory, ClassificationMetrics>;\n}\n\nexport interface LatencyMetrics {\n /** Median latency (p50) */\n p50: number;\n /** 95th percentile latency */\n p95: number;\n /** 99th percentile latency */\n p99: number;\n /** Mean latency */\n mean: number;\n /** Standard deviation */\n stdDev: number;\n}\n\nexport interface TokenMetrics {\n /** Total input tokens */\n totalInputTokens: number;\n /** Total output tokens */\n totalOutputTokens: number;\n /** Average tokens per sample */\n avgTokensPerSample: number;\n}\n\nexport interface CalibrationMetrics {\n /** Expected Calibration Error */\n ece: number;\n /** Maximum Calibration Error */\n mce: number;\n /** Brier Score */\n brierScore: number;\n /** Reliability diagram data */\n reliabilityDiagram: Array<{\n binStart: number;\n binEnd: number;\n avgConfidence: number;\n avgAccuracy: number;\n count: number;\n }>;\n}\n\nexport interface DifficultyBreakdown {\n /** Metrics by difficulty level */\n byDifficulty: Record<DifficultyLevel, ClassificationMetrics>;\n}\n\nexport interface FrameworkBreakdown {\n /** Metrics by framework */\n byFramework: Record<Framework, ClassificationMetrics>;\n}\n\nexport interface EvaluationResult {\n /** System name */\n systemName: string;\n /** System version */\n version: string;\n /** Evaluation timestamp */\n evaluatedAt: string;\n /** Benchmark version used */\n benchmarkVersion: string;\n /** Total samples evaluated */\n totalSamples: number;\n /** Primary metrics */\n classification: ClassificationMetrics;\n /** Confusion matrix */\n confusionMatrix: ConfusionMatrix;\n /** Severity accuracy metrics */\n severity: SeverityMetrics;\n /** Category accuracy metrics */\n category: CategoryMetrics;\n /** Latency metrics */\n latency: LatencyMetrics;\n /** Token usage metrics */\n tokens: TokenMetrics;\n /** Calibration metrics */\n calibration: CalibrationMetrics;\n /** Breakdown by difficulty */\n difficulty: DifficultyBreakdown;\n /** Breakdown by framework */\n framework: FrameworkBreakdown;\n}\n\n// ============================================================================\n// Leaderboard Types\n// ============================================================================\n\nexport interface LeaderboardEntry {\n /** Rank position */\n rank: number;\n /** System name */\n systemName: string;\n /** System version */\n version: string;\n /** F1 score (primary ranking metric) */\n f1: number;\n /** Accuracy */\n accuracy: number;\n /** Precision */\n precision: number;\n /** Recall */\n recall: number;\n /** Severity accuracy */\n severityAccuracy: number;\n /** Calibration error (ECE) */\n ece: number;\n /** Median latency */\n latencyP50: number;\n /** Average tokens per sample */\n tokensPerSample: number;\n /** Submission date */\n submittedAt: string;\n /** Is this the current best? */\n isBest: boolean;\n}\n\nexport interface Leaderboard {\n /** Last updated timestamp */\n lastUpdated: string;\n /** Benchmark version */\n benchmarkVersion: string;\n /** Total samples in benchmark */\n totalSamples: number;\n /** Leaderboard entries sorted by F1 score */\n entries: LeaderboardEntry[];\n}\n\n// ============================================================================\n// Dataset Configuration\n// ============================================================================\n\nexport interface BenchmarkConfig {\n /** Benchmark version */\n version: string;\n /** Dataset name */\n name: string;\n /** Dataset description */\n description: string;\n /** Total sample count */\n sampleCount: number;\n /** Categories included */\n categories: BenchmarkCategory[];\n /** Frameworks included */\n frameworks: Framework[];\n /** Difficulty distribution */\n difficultyDistribution: Record<DifficultyLevel, number>;\n /** Status distribution */\n statusDistribution: Record<DriftStatus, number>;\n /** License */\n license: string;\n /** Contact for submissions */\n submissionContact: string;\n}\n\nexport interface BenchmarkDataset {\n /** Configuration metadata */\n config: BenchmarkConfig;\n /** All samples */\n samples: BenchmarkSample[];\n}\n","/**\n * VasperaBench Dataset Loader\n *\n * Handles loading, validating, and managing the VasperaBench dataset.\n * Supports loading from JSON files or inline data.\n */\n\nimport { readFile, writeFile, readdir } from 'fs/promises';\nimport { join, basename } from 'path';\nimport type {\n BenchmarkSample,\n BenchmarkDataset,\n BenchmarkConfig,\n BenchmarkCategory,\n Framework,\n DifficultyLevel,\n DriftStatus,\n} from './types.js';\n\n// ============================================================================\n// Dataset Loading\n// ============================================================================\n\n/**\n * Load the full benchmark dataset from a JSON file\n */\nexport async function loadDataset(path: string): Promise<BenchmarkDataset> {\n const content = await readFile(path, 'utf-8');\n const data = JSON.parse(content) as BenchmarkDataset;\n validateDataset(data);\n return data;\n}\n\n/**\n * Load samples from a directory structure\n */\nexport async function loadSamplesFromDirectory(basePath: string): Promise<BenchmarkSample[]> {\n const samples: BenchmarkSample[] = [];\n const frameworks = await readdir(basePath);\n\n for (const framework of frameworks) {\n const frameworkPath = join(basePath, framework);\n const statuses = await readdir(frameworkPath).catch(() => []);\n\n for (const status of statuses) {\n const statusPath = join(frameworkPath, status);\n const sampleDirs = await readdir(statusPath).catch(() => []);\n\n for (const sampleDir of sampleDirs) {\n const samplePath = join(statusPath, sampleDir);\n try {\n const sample = await loadSampleFromDirectory(samplePath);\n if (sample) {\n samples.push(sample);\n }\n } catch {\n // Skip invalid samples\n }\n }\n }\n }\n\n return samples;\n}\n\n/**\n * Load a single sample from a directory containing docs.md, code.ts, and label.json\n */\nasync function loadSampleFromDirectory(path: string): Promise<BenchmarkSample | null> {\n try {\n const files = await readdir(path);\n\n // Find documentation file (docs.md, docs.txt, etc.)\n const docFile = files.find((f) => f.startsWith('docs.'));\n // Find code file\n const codeFile = files.find(\n (f) =>\n f.startsWith('code.') &&\n (f.endsWith('.ts') || f.endsWith('.js') || f.endsWith('.py') || f.endsWith('.java'))\n );\n // Find label file\n const labelFile = files.find((f) => f === 'label.json');\n\n if (!docFile || !codeFile || !labelFile) {\n return null;\n }\n\n const docContent = await readFile(join(path, docFile), 'utf-8');\n const codeContent = await readFile(join(path, codeFile), 'utf-8');\n const labelContent = await readFile(join(path, labelFile), 'utf-8');\n const label = JSON.parse(labelContent);\n\n // Extract metadata from path structure\n const pathParts = path.split('/');\n const sampleId = pathParts.slice(-3).join('-');\n const status = pathParts[pathParts.length - 2] as 'drift' | 'verified' | 'undocumented';\n const framework = pathParts[pathParts.length - 3] as Framework;\n\n const codeExt = codeFile.split('.').pop() || 'ts';\n const language =\n {\n ts: 'typescript',\n js: 'javascript',\n py: 'python',\n java: 'java',\n go: 'go',\n }[codeExt] || 'typescript';\n\n return {\n id: sampleId,\n category: label.category || 'api-contracts',\n framework,\n difficulty: label.difficulty || 'medium',\n documentation: {\n content: docContent,\n source: `docs/${docFile}`,\n section: label.section || 'Main',\n },\n code: {\n content: codeContent,\n file: `src/${codeFile}`,\n language,\n },\n label: {\n status: status === 'drift' ? 'drift' : status === 'verified' ? 'verified' : 'undocumented',\n severity: label.severity,\n driftType: label.driftType,\n explanation: label.explanation,\n recommendation: label.recommendation,\n },\n metadata: {\n contributor: label.contributor || 'vaspera-team',\n verified: label.verified ?? true,\n added: label.added || new Date().toISOString().split('T')[0],\n version: '1.0.0',\n },\n };\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Dataset Validation\n// ============================================================================\n\n/**\n * Validate a dataset structure\n */\nexport function validateDataset(dataset: BenchmarkDataset): void {\n if (!dataset.config) {\n throw new Error('Dataset missing config');\n }\n if (!dataset.samples || !Array.isArray(dataset.samples)) {\n throw new Error('Dataset missing samples array');\n }\n\n for (const sample of dataset.samples) {\n validateSample(sample);\n }\n}\n\n/**\n * Validate a single sample\n */\nexport function validateSample(sample: BenchmarkSample): void {\n if (!sample.id) {\n throw new Error('Sample missing id');\n }\n if (!sample.documentation?.content) {\n throw new Error(`Sample ${sample.id} missing documentation content`);\n }\n if (!sample.code?.content) {\n throw new Error(`Sample ${sample.id} missing code content`);\n }\n if (!sample.label?.status) {\n throw new Error(`Sample ${sample.id} missing label status`);\n }\n if (!sample.label?.explanation) {\n throw new Error(`Sample ${sample.id} missing label explanation`);\n }\n}\n\n// ============================================================================\n// Dataset Statistics\n// ============================================================================\n\n/**\n * Calculate dataset statistics\n */\nexport function calculateDatasetStats(\n samples: BenchmarkSample[]\n): Pick<BenchmarkConfig, 'difficultyDistribution' | 'statusDistribution'> & {\n categoryCount: Record<BenchmarkCategory, number>;\n frameworkCount: Record<Framework, number>;\n} {\n const difficultyDistribution: Record<DifficultyLevel, number> = {\n easy: 0,\n medium: 0,\n hard: 0,\n expert: 0,\n };\n const statusDistribution: Record<DriftStatus, number> = {\n verified: 0,\n drift: 0,\n undocumented: 0,\n unimplemented: 0,\n };\n const categoryCount: Record<BenchmarkCategory, number> = {\n 'api-contracts': 0,\n 'rate-limits': 0,\n 'auth-flows': 0,\n 'config-values': 0,\n 'error-handling': 0,\n 'data-models': 0,\n security: 0,\n performance: 0,\n };\n const frameworkCount: Record<Framework, number> = {\n nextjs: 0,\n express: 0,\n django: 0,\n 'spring-boot': 0,\n fastapi: 0,\n rails: 0,\n laravel: 0,\n generic: 0,\n };\n\n for (const sample of samples) {\n difficultyDistribution[sample.difficulty]++;\n statusDistribution[sample.label.status]++;\n categoryCount[sample.category]++;\n frameworkCount[sample.framework]++;\n }\n\n return {\n difficultyDistribution,\n statusDistribution,\n categoryCount,\n frameworkCount,\n };\n}\n\n// ============================================================================\n// Dataset Export\n// ============================================================================\n\n/**\n * Export dataset to JSON file\n */\nexport async function exportDataset(dataset: BenchmarkDataset, path: string): Promise<void> {\n const content = JSON.stringify(dataset, null, 2);\n await writeFile(path, content, 'utf-8');\n}\n\n/**\n * Create a dataset from samples with auto-generated config\n */\nexport function createDataset(\n samples: BenchmarkSample[],\n name: string = 'VasperaBench',\n version: string = '1.0.0'\n): BenchmarkDataset {\n const stats = calculateDatasetStats(samples);\n\n const config: BenchmarkConfig = {\n version,\n name,\n description: 'VasperaBench: A benchmark dataset for doc-code drift detection',\n sampleCount: samples.length,\n categories: Object.keys(stats.categoryCount).filter(\n (k) => stats.categoryCount[k as BenchmarkCategory] > 0\n ) as BenchmarkCategory[],\n frameworks: Object.keys(stats.frameworkCount).filter(\n (k) => stats.frameworkCount[k as Framework] > 0\n ) as Framework[],\n difficultyDistribution: stats.difficultyDistribution,\n statusDistribution: stats.statusDistribution,\n license: 'MIT',\n submissionContact: 'benchmark@vasperapm.dev',\n };\n\n return { config, samples };\n}\n\n// ============================================================================\n// Sample Filtering\n// ============================================================================\n\nexport interface FilterOptions {\n categories?: BenchmarkCategory[];\n frameworks?: Framework[];\n difficulties?: DifficultyLevel[];\n statuses?: DriftStatus[];\n verified?: boolean;\n}\n\n/**\n * Filter samples by various criteria\n */\nexport function filterSamples(\n samples: BenchmarkSample[],\n options: FilterOptions\n): BenchmarkSample[] {\n return samples.filter((sample) => {\n if (options.categories && !options.categories.includes(sample.category)) {\n return false;\n }\n if (options.frameworks && !options.frameworks.includes(sample.framework)) {\n return false;\n }\n if (options.difficulties && !options.difficulties.includes(sample.difficulty)) {\n return false;\n }\n if (options.statuses && !options.statuses.includes(sample.label.status)) {\n return false;\n }\n if (options.verified !== undefined && sample.metadata.verified !== options.verified) {\n return false;\n }\n return true;\n });\n}\n\n/**\n * Split dataset into train/test sets\n */\nexport function splitDataset(\n samples: BenchmarkSample[],\n testRatio: number = 0.2,\n seed?: number\n): { train: BenchmarkSample[]; test: BenchmarkSample[] } {\n // Deterministic shuffle if seed provided\n const shuffled = [...samples];\n const random = seed !== undefined ? seededRandom(seed) : Math.random;\n\n for (let i = shuffled.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];\n }\n\n const splitIndex = Math.floor(shuffled.length * (1 - testRatio));\n return {\n train: shuffled.slice(0, splitIndex),\n test: shuffled.slice(splitIndex),\n };\n}\n\n/**\n * Simple seeded random number generator\n */\nfunction seededRandom(seed: number): () => number {\n return () => {\n seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n return seed / 0x7fffffff;\n };\n}\n","/**\n * VasperaBench Evaluation Metrics\n *\n * Implements standard evaluation metrics for doc-code drift detection:\n * - Classification metrics (accuracy, precision, recall, F1)\n * - Severity accuracy\n * - Category accuracy\n * - Calibration metrics (ECE, MCE, Brier)\n * - Latency and token metrics\n */\n\nimport type {\n BenchmarkSample,\n SystemPrediction,\n ClassificationMetrics,\n ConfusionMatrix,\n SeverityMetrics,\n CategoryMetrics,\n LatencyMetrics,\n TokenMetrics,\n CalibrationMetrics,\n DifficultyBreakdown,\n FrameworkBreakdown,\n EvaluationResult,\n DriftStatus,\n DriftSeverity,\n BenchmarkCategory,\n DifficultyLevel,\n Framework,\n} from '../types.js';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a status represents drift\n */\nfunction isDrift(status: DriftStatus): boolean {\n return status === 'drift';\n}\n\n/**\n * Calculate mean of an array\n */\nfunction mean(values: number[]): number {\n if (values.length === 0) return 0;\n return values.reduce((a, b) => a + b, 0) / values.length;\n}\n\n/**\n * Calculate standard deviation\n */\nfunction stdDev(values: number[]): number {\n if (values.length === 0) return 0;\n const avg = mean(values);\n const squareDiffs = values.map((v) => Math.pow(v - avg, 2));\n return Math.sqrt(mean(squareDiffs));\n}\n\n/**\n * Calculate percentile\n */\nfunction percentile(values: number[], p: number): number {\n if (values.length === 0) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, index)];\n}\n\n// ============================================================================\n// Confusion Matrix\n// ============================================================================\n\n/**\n * Build confusion matrix for binary drift detection\n */\nexport function buildConfusionMatrix(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>\n): ConfusionMatrix {\n let tp = 0;\n let tn = 0;\n let fp = 0;\n let fn = 0;\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n const actualDrift = isDrift(sample.label.status);\n const predictedDrift = isDrift(prediction.predictedStatus);\n\n if (actualDrift && predictedDrift) tp++;\n else if (!actualDrift && !predictedDrift) tn++;\n else if (!actualDrift && predictedDrift) fp++;\n else if (actualDrift && !predictedDrift) fn++;\n }\n\n return { truePositives: tp, trueNegatives: tn, falsePositives: fp, falseNegatives: fn };\n}\n\n// ============================================================================\n// Classification Metrics\n// ============================================================================\n\n/**\n * Calculate classification metrics from confusion matrix\n */\nexport function calculateClassificationMetrics(matrix: ConfusionMatrix): ClassificationMetrics {\n const { truePositives: tp, trueNegatives: tn, falsePositives: fp, falseNegatives: fn } = matrix;\n\n const total = tp + tn + fp + fn;\n const accuracy = total > 0 ? (tp + tn) / total : 0;\n const precision = tp + fp > 0 ? tp / (tp + fp) : 0;\n const recall = tp + fn > 0 ? tp / (tp + fn) : 0;\n const f1 = precision + recall > 0 ? (2 * precision * recall) / (precision + recall) : 0;\n\n // Matthews Correlation Coefficient\n const mccNumerator = tp * tn - fp * fn;\n const mccDenominator = Math.sqrt((tp + fp) * (tp + fn) * (tn + fp) * (tn + fn));\n const mcc = mccDenominator > 0 ? mccNumerator / mccDenominator : 0;\n\n return { accuracy, precision, recall, f1, mcc };\n}\n\n// ============================================================================\n// Severity Metrics\n// ============================================================================\n\n/**\n * Calculate severity accuracy for correctly identified drift\n */\nexport function calculateSeverityMetrics(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>\n): SeverityMetrics {\n const severityLevels: DriftSeverity[] = ['critical', 'high', 'medium', 'low'];\n const bySeverity: Record<DriftSeverity, ConfusionMatrix> = {\n critical: { truePositives: 0, trueNegatives: 0, falsePositives: 0, falseNegatives: 0 },\n high: { truePositives: 0, trueNegatives: 0, falsePositives: 0, falseNegatives: 0 },\n medium: { truePositives: 0, trueNegatives: 0, falsePositives: 0, falseNegatives: 0 },\n low: { truePositives: 0, trueNegatives: 0, falsePositives: 0, falseNegatives: 0 },\n };\n\n let correctSeverity = 0;\n let totalSeverityPredictions = 0;\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n // Only evaluate severity when both have drift\n if (isDrift(sample.label.status) && isDrift(prediction.predictedStatus)) {\n totalSeverityPredictions++;\n const actualSeverity = sample.label.severity;\n const predictedSeverity = prediction.predictedSeverity;\n\n if (actualSeverity && predictedSeverity) {\n if (actualSeverity === predictedSeverity) {\n correctSeverity++;\n }\n\n // Update per-severity confusion matrix\n for (const level of severityLevels) {\n const isActual = actualSeverity === level;\n const isPredicted = predictedSeverity === level;\n\n if (isActual && isPredicted) bySeverity[level].truePositives++;\n else if (!isActual && !isPredicted) bySeverity[level].trueNegatives++;\n else if (!isActual && isPredicted) bySeverity[level].falsePositives++;\n else if (isActual && !isPredicted) bySeverity[level].falseNegatives++;\n }\n }\n }\n }\n\n const severityAccuracy =\n totalSeverityPredictions > 0 ? correctSeverity / totalSeverityPredictions : 0;\n\n const bySeverityMetrics: Record<DriftSeverity, ClassificationMetrics> = {} as Record<\n DriftSeverity,\n ClassificationMetrics\n >;\n for (const level of severityLevels) {\n bySeverityMetrics[level] = calculateClassificationMetrics(bySeverity[level]);\n }\n\n return { severityAccuracy, bySeverity: bySeverityMetrics };\n}\n\n// ============================================================================\n// Category Metrics\n// ============================================================================\n\n/**\n * Calculate category/drift-type accuracy\n */\nexport function calculateCategoryMetrics(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>\n): CategoryMetrics {\n const categories: BenchmarkCategory[] = [\n 'api-contracts',\n 'rate-limits',\n 'auth-flows',\n 'config-values',\n 'error-handling',\n 'data-models',\n 'security',\n 'performance',\n ];\n\n const byCategory: Record<BenchmarkCategory, ConfusionMatrix> = {} as Record<\n BenchmarkCategory,\n ConfusionMatrix\n >;\n for (const cat of categories) {\n byCategory[cat] = { truePositives: 0, trueNegatives: 0, falsePositives: 0, falseNegatives: 0 };\n }\n\n let correctCategory = 0;\n let totalCategoryPredictions = 0;\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n const actualCategory = sample.category;\n\n // For category classification, evaluate all predictions\n totalCategoryPredictions++;\n\n // Calculate binary classification for each category\n for (const cat of categories) {\n const actualIsCat = actualCategory === cat;\n const predictedIsCat = actualCategory === cat; // Predictions don't predict category, so we just track actual\n\n // For drift detection within category\n if (actualIsCat) {\n const actualDrift = isDrift(sample.label.status);\n const predictedDrift = isDrift(prediction.predictedStatus);\n\n if (actualDrift && predictedDrift) byCategory[cat].truePositives++;\n else if (!actualDrift && !predictedDrift) byCategory[cat].trueNegatives++;\n else if (!actualDrift && predictedDrift) byCategory[cat].falsePositives++;\n else if (actualDrift && !predictedDrift) byCategory[cat].falseNegatives++;\n }\n }\n\n // Check if drift type prediction matches (if applicable)\n if (\n isDrift(sample.label.status) &&\n isDrift(prediction.predictedStatus) &&\n sample.label.driftType &&\n prediction.predictedDriftType\n ) {\n if (sample.label.driftType === prediction.predictedDriftType) {\n correctCategory++;\n }\n }\n }\n\n const categoryAccuracy =\n totalCategoryPredictions > 0 ? correctCategory / totalCategoryPredictions : 0;\n\n const byCategoryMetrics: Record<BenchmarkCategory, ClassificationMetrics> = {} as Record<\n BenchmarkCategory,\n ClassificationMetrics\n >;\n for (const cat of categories) {\n byCategoryMetrics[cat] = calculateClassificationMetrics(byCategory[cat]);\n }\n\n return { categoryAccuracy, byCategory: byCategoryMetrics };\n}\n\n// ============================================================================\n// Latency Metrics\n// ============================================================================\n\n/**\n * Calculate latency metrics from predictions\n */\nexport function calculateLatencyMetrics(predictions: SystemPrediction[]): LatencyMetrics {\n const latencies = predictions\n .filter((p) => p.latencyMs !== undefined)\n .map((p) => p.latencyMs as number);\n\n if (latencies.length === 0) {\n return { p50: 0, p95: 0, p99: 0, mean: 0, stdDev: 0 };\n }\n\n return {\n p50: percentile(latencies, 50),\n p95: percentile(latencies, 95),\n p99: percentile(latencies, 99),\n mean: mean(latencies),\n stdDev: stdDev(latencies),\n };\n}\n\n// ============================================================================\n// Token Metrics\n// ============================================================================\n\n/**\n * Calculate token usage metrics\n */\nexport function calculateTokenMetrics(predictions: SystemPrediction[]): TokenMetrics {\n let totalInput = 0;\n let totalOutput = 0;\n let count = 0;\n\n for (const p of predictions) {\n if (p.tokensUsed) {\n totalInput += p.tokensUsed.input;\n totalOutput += p.tokensUsed.output;\n count++;\n }\n }\n\n return {\n totalInputTokens: totalInput,\n totalOutputTokens: totalOutput,\n avgTokensPerSample: count > 0 ? (totalInput + totalOutput) / count : 0,\n };\n}\n\n// ============================================================================\n// Calibration Metrics\n// ============================================================================\n\n/**\n * Calculate calibration metrics (ECE, MCE, Brier)\n */\nexport function calculateCalibrationMetrics(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>,\n numBins: number = 10\n): CalibrationMetrics {\n // Build reliability diagram data\n const bins: Array<{ confidences: number[]; accuracies: number[] }> = [];\n for (let i = 0; i < numBins; i++) {\n bins.push({ confidences: [], accuracies: [] });\n }\n\n let brierSum = 0;\n let totalPredictions = 0;\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n totalPredictions++;\n const confidence = prediction.confidence;\n const isCorrect = sample.label.status === prediction.predictedStatus ? 1 : 0;\n\n // Calculate Brier score contribution\n brierSum += Math.pow(confidence - isCorrect, 2);\n\n // Assign to bin\n const binIndex = Math.min(Math.floor(confidence * numBins), numBins - 1);\n bins[binIndex].confidences.push(confidence);\n bins[binIndex].accuracies.push(isCorrect);\n }\n\n // Calculate ECE and MCE\n let ece = 0;\n let mce = 0;\n const reliabilityDiagram: CalibrationMetrics['reliabilityDiagram'] = [];\n\n for (let i = 0; i < numBins; i++) {\n const binStart = i / numBins;\n const binEnd = (i + 1) / numBins;\n const binConfidences = bins[i].confidences;\n const binAccuracies = bins[i].accuracies;\n const count = binConfidences.length;\n\n if (count > 0) {\n const avgConfidence = mean(binConfidences);\n const avgAccuracy = mean(binAccuracies);\n const calibrationError = Math.abs(avgAccuracy - avgConfidence);\n\n // Weighted contribution to ECE\n ece += (count / totalPredictions) * calibrationError;\n\n // Update MCE\n mce = Math.max(mce, calibrationError);\n\n reliabilityDiagram.push({\n binStart,\n binEnd,\n avgConfidence,\n avgAccuracy,\n count,\n });\n } else {\n reliabilityDiagram.push({\n binStart,\n binEnd,\n avgConfidence: 0,\n avgAccuracy: 0,\n count: 0,\n });\n }\n }\n\n const brierScore = totalPredictions > 0 ? brierSum / totalPredictions : 0;\n\n return { ece, mce, brierScore, reliabilityDiagram };\n}\n\n// ============================================================================\n// Difficulty Breakdown\n// ============================================================================\n\n/**\n * Calculate metrics by difficulty level\n */\nexport function calculateDifficultyBreakdown(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>\n): DifficultyBreakdown {\n const difficulties: DifficultyLevel[] = ['easy', 'medium', 'hard', 'expert'];\n\n const byDifficulty: Record<DifficultyLevel, ConfusionMatrix> = {} as Record<\n DifficultyLevel,\n ConfusionMatrix\n >;\n for (const diff of difficulties) {\n byDifficulty[diff] = {\n truePositives: 0,\n trueNegatives: 0,\n falsePositives: 0,\n falseNegatives: 0,\n };\n }\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n const diff = sample.difficulty;\n const actualDrift = isDrift(sample.label.status);\n const predictedDrift = isDrift(prediction.predictedStatus);\n\n if (actualDrift && predictedDrift) byDifficulty[diff].truePositives++;\n else if (!actualDrift && !predictedDrift) byDifficulty[diff].trueNegatives++;\n else if (!actualDrift && predictedDrift) byDifficulty[diff].falsePositives++;\n else if (actualDrift && !predictedDrift) byDifficulty[diff].falseNegatives++;\n }\n\n const byDifficultyMetrics: Record<DifficultyLevel, ClassificationMetrics> = {} as Record<\n DifficultyLevel,\n ClassificationMetrics\n >;\n for (const diff of difficulties) {\n byDifficultyMetrics[diff] = calculateClassificationMetrics(byDifficulty[diff]);\n }\n\n return { byDifficulty: byDifficultyMetrics };\n}\n\n// ============================================================================\n// Framework Breakdown\n// ============================================================================\n\n/**\n * Calculate metrics by framework\n */\nexport function calculateFrameworkBreakdown(\n samples: BenchmarkSample[],\n predictions: Map<string, SystemPrediction>\n): FrameworkBreakdown {\n const frameworks: Framework[] = [\n 'nextjs',\n 'express',\n 'django',\n 'spring-boot',\n 'fastapi',\n 'rails',\n 'laravel',\n 'generic',\n ];\n\n const byFramework: Record<Framework, ConfusionMatrix> = {} as Record<Framework, ConfusionMatrix>;\n for (const fw of frameworks) {\n byFramework[fw] = {\n truePositives: 0,\n trueNegatives: 0,\n falsePositives: 0,\n falseNegatives: 0,\n };\n }\n\n for (const sample of samples) {\n const prediction = predictions.get(sample.id);\n if (!prediction) continue;\n\n const fw = sample.framework;\n const actualDrift = isDrift(sample.label.status);\n const predictedDrift = isDrift(prediction.predictedStatus);\n\n if (actualDrift && predictedDrift) byFramework[fw].truePositives++;\n else if (!actualDrift && !predictedDrift) byFramework[fw].trueNegatives++;\n else if (!actualDrift && predictedDrift) byFramework[fw].falsePositives++;\n else if (actualDrift && !predictedDrift) byFramework[fw].falseNegatives++;\n }\n\n const byFrameworkMetrics: Record<Framework, ClassificationMetrics> = {} as Record<\n Framework,\n ClassificationMetrics\n >;\n for (const fw of frameworks) {\n byFrameworkMetrics[fw] = calculateClassificationMetrics(byFramework[fw]);\n }\n\n return { byFramework: byFrameworkMetrics };\n}\n\n// ============================================================================\n// Full Evaluation\n// ============================================================================\n\n/**\n * Run full evaluation on a system's predictions\n */\nexport function evaluateSystem(\n samples: BenchmarkSample[],\n predictions: SystemPrediction[],\n systemName: string,\n version: string,\n benchmarkVersion: string\n): EvaluationResult {\n // Build prediction map for easy lookup\n const predictionMap = new Map<string, SystemPrediction>();\n for (const p of predictions) {\n predictionMap.set(p.sampleId, p);\n }\n\n // Calculate all metrics\n const confusionMatrix = buildConfusionMatrix(samples, predictionMap);\n const classification = calculateClassificationMetrics(confusionMatrix);\n const severity = calculateSeverityMetrics(samples, predictionMap);\n const category = calculateCategoryMetrics(samples, predictionMap);\n const latency = calculateLatencyMetrics(predictions);\n const tokens = calculateTokenMetrics(predictions);\n const calibration = calculateCalibrationMetrics(samples, predictionMap);\n const difficulty = calculateDifficultyBreakdown(samples, predictionMap);\n const framework = calculateFrameworkBreakdown(samples, predictionMap);\n\n return {\n systemName,\n version,\n evaluatedAt: new Date().toISOString(),\n benchmarkVersion,\n totalSamples: samples.length,\n classification,\n confusionMatrix,\n severity,\n category,\n latency,\n tokens,\n calibration,\n difficulty,\n framework,\n };\n}\n\n/**\n * Generate a summary report as markdown\n */\nexport function generateMarkdownReport(result: EvaluationResult): string {\n const lines: string[] = [];\n\n lines.push(`# VasperaBench Evaluation Report`);\n lines.push('');\n lines.push(`**System:** ${result.systemName} v${result.version}`);\n lines.push(`**Evaluated:** ${result.evaluatedAt}`);\n lines.push(`**Benchmark Version:** ${result.benchmarkVersion}`);\n lines.push(`**Total Samples:** ${result.totalSamples}`);\n lines.push('');\n\n lines.push('## Classification Metrics');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Accuracy | ${(result.classification.accuracy * 100).toFixed(2)}% |`);\n lines.push(`| Precision | ${(result.classification.precision * 100).toFixed(2)}% |`);\n lines.push(`| Recall | ${(result.classification.recall * 100).toFixed(2)}% |`);\n lines.push(`| **F1 Score** | **${(result.classification.f1 * 100).toFixed(2)}%** |`);\n if (result.classification.mcc !== undefined) {\n lines.push(`| MCC | ${result.classification.mcc.toFixed(4)} |`);\n }\n lines.push('');\n\n lines.push('## Confusion Matrix');\n lines.push('');\n lines.push('| | Predicted Drift | Predicted Verified |');\n lines.push('|--|-----------------|-------------------|');\n lines.push(\n `| **Actual Drift** | ${result.confusionMatrix.truePositives} (TP) | ${result.confusionMatrix.falseNegatives} (FN) |`\n );\n lines.push(\n `| **Actual Verified** | ${result.confusionMatrix.falsePositives} (FP) | ${result.confusionMatrix.trueNegatives} (TN) |`\n );\n lines.push('');\n\n lines.push('## Severity & Category Accuracy');\n lines.push('');\n lines.push(`- **Severity Accuracy:** ${(result.severity.severityAccuracy * 100).toFixed(2)}%`);\n lines.push(`- **Category Accuracy:** ${(result.category.categoryAccuracy * 100).toFixed(2)}%`);\n lines.push('');\n\n lines.push('## Calibration');\n lines.push('');\n lines.push(`- **ECE:** ${(result.calibration.ece * 100).toFixed(2)}%`);\n lines.push(`- **MCE:** ${(result.calibration.mce * 100).toFixed(2)}%`);\n lines.push(`- **Brier Score:** ${result.calibration.brierScore.toFixed(4)}`);\n lines.push('');\n\n lines.push('## Performance');\n lines.push('');\n lines.push(`- **Latency (p50):** ${result.latency.p50.toFixed(0)}ms`);\n lines.push(`- **Latency (p95):** ${result.latency.p95.toFixed(0)}ms`);\n lines.push(`- **Avg Tokens/Sample:** ${result.tokens.avgTokensPerSample.toFixed(0)}`);\n lines.push('');\n\n lines.push('## Performance by Difficulty');\n lines.push('');\n lines.push('| Difficulty | F1 Score | Accuracy |');\n lines.push('|------------|----------|----------|');\n for (const [diff, metrics] of Object.entries(result.difficulty.byDifficulty)) {\n lines.push(\n `| ${diff} | ${(metrics.f1 * 100).toFixed(2)}% | ${(metrics.accuracy * 100).toFixed(2)}% |`\n );\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n","/**\n * VasperaBench Runner\n *\n * Runs a verification system against the VasperaBench dataset and produces\n * evaluation results. Supports both single-sample and batch evaluation.\n */\n\nimport type {\n BenchmarkSample,\n BenchmarkDataset,\n SystemPrediction,\n SystemSubmission,\n EvaluationResult,\n LeaderboardEntry,\n Leaderboard,\n DriftStatus,\n DriftSeverity,\n DriftType,\n} from '../types.js';\nimport { evaluateSystem, generateMarkdownReport } from './metrics.js';\n\n// ============================================================================\n// Verification System Interface\n// ============================================================================\n\n/**\n * Interface for a verification system that can be evaluated\n */\nexport interface VerificationSystem {\n /** System name */\n name: string;\n /** System version */\n version: string;\n /** Model used (if applicable) */\n model?: string;\n\n /**\n * Verify a single doc-code pair\n */\n verify(\n documentation: string,\n code: string,\n context?: VerificationContext\n ): Promise<VerificationResult>;\n}\n\nexport interface VerificationContext {\n framework?: string;\n category?: string;\n docSource?: string;\n codeFile?: string;\n}\n\nexport interface VerificationResult {\n status: DriftStatus;\n confidence: number;\n severity?: DriftSeverity;\n driftType?: DriftType;\n reasoning?: string;\n tokensUsed?: { input: number; output: number };\n}\n\n// ============================================================================\n// Benchmark Runner\n// ============================================================================\n\nexport interface RunnerOptions {\n /** Maximum concurrent verifications */\n concurrency?: number;\n /** Timeout per sample in milliseconds */\n timeoutMs?: number;\n /** Filter by category */\n categories?: string[];\n /** Filter by framework */\n frameworks?: string[];\n /** Filter by difficulty */\n difficulties?: string[];\n /** Progress callback */\n onProgress?: (completed: number, total: number) => void;\n /** Error callback */\n onError?: (sampleId: string, error: Error) => void;\n}\n\n/**\n * Run benchmark against a verification system\n */\nexport async function runBenchmark(\n system: VerificationSystem,\n dataset: BenchmarkDataset,\n options: RunnerOptions = {}\n): Promise<SystemSubmission> {\n const { concurrency = 5, timeoutMs = 30000, onProgress, onError } = options;\n\n // Filter samples if needed\n let samples = dataset.samples;\n\n if (options.categories?.length) {\n samples = samples.filter((s) => options.categories!.includes(s.category));\n }\n if (options.frameworks?.length) {\n samples = samples.filter((s) => options.frameworks!.includes(s.framework));\n }\n if (options.difficulties?.length) {\n samples = samples.filter((s) => options.difficulties!.includes(s.difficulty));\n }\n\n const predictions: SystemPrediction[] = [];\n let completed = 0;\n\n // Process samples with concurrency limit\n const processSample = async (sample: BenchmarkSample): Promise<SystemPrediction | null> => {\n const startTime = Date.now();\n\n try {\n const result = await Promise.race([\n system.verify(sample.documentation.content, sample.code.content, {\n framework: sample.framework,\n category: sample.category,\n docSource: sample.documentation.source,\n codeFile: sample.code.file,\n }),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Timeout')), timeoutMs)\n ),\n ]);\n\n const latencyMs = Date.now() - startTime;\n\n return {\n sampleId: sample.id,\n predictedStatus: result.status,\n confidence: result.confidence,\n predictedSeverity: result.severity,\n predictedDriftType: result.driftType,\n reasoning: result.reasoning,\n tokensUsed: result.tokensUsed,\n latencyMs,\n };\n } catch (error) {\n onError?.(sample.id, error as Error);\n return null;\n } finally {\n completed++;\n onProgress?.(completed, samples.length);\n }\n };\n\n // Process in batches for concurrency control\n for (let i = 0; i < samples.length; i += concurrency) {\n const batch = samples.slice(i, i + concurrency);\n const results = await Promise.all(batch.map(processSample));\n\n for (const result of results) {\n if (result) {\n predictions.push(result);\n }\n }\n }\n\n return {\n systemName: system.name,\n version: system.version,\n submittedAt: new Date().toISOString(),\n model: system.model,\n predictions,\n };\n}\n\n/**\n * Evaluate a submission and generate results\n */\nexport function evaluateSubmission(\n submission: SystemSubmission,\n dataset: BenchmarkDataset\n): EvaluationResult {\n return evaluateSystem(\n dataset.samples,\n submission.predictions,\n submission.systemName,\n submission.version,\n dataset.config.version\n );\n}\n\n// ============================================================================\n// Leaderboard Management\n// ============================================================================\n\n/**\n * Create a leaderboard entry from evaluation results\n */\nexport function createLeaderboardEntry(\n result: EvaluationResult,\n rank: number = 0\n): LeaderboardEntry {\n return {\n rank,\n systemName: result.systemName,\n version: result.version,\n f1: result.classification.f1,\n accuracy: result.classification.accuracy,\n precision: result.classification.precision,\n recall: result.classification.recall,\n severityAccuracy: result.severity.severityAccuracy,\n ece: result.calibration.ece,\n latencyP50: result.latency.p50,\n tokensPerSample: result.tokens.avgTokensPerSample,\n submittedAt: result.evaluatedAt,\n isBest: false,\n };\n}\n\n/**\n * Update leaderboard with a new result\n */\nexport function updateLeaderboard(\n leaderboard: Leaderboard,\n result: EvaluationResult\n): Leaderboard {\n const newEntry = createLeaderboardEntry(result);\n\n // Check if this system/version already exists\n const existingIndex = leaderboard.entries.findIndex(\n (e) => e.systemName === result.systemName && e.version === result.version\n );\n\n if (existingIndex >= 0) {\n // Update existing entry\n leaderboard.entries[existingIndex] = newEntry;\n } else {\n // Add new entry\n leaderboard.entries.push(newEntry);\n }\n\n // Sort by F1 score (descending)\n leaderboard.entries.sort((a, b) => b.f1 - a.f1);\n\n // Update ranks and best flag\n let bestF1 = 0;\n for (let i = 0; i < leaderboard.entries.length; i++) {\n leaderboard.entries[i].rank = i + 1;\n if (leaderboard.entries[i].f1 > bestF1) {\n bestF1 = leaderboard.entries[i].f1;\n }\n }\n\n // Mark best entries\n for (const entry of leaderboard.entries) {\n entry.isBest = entry.f1 === bestF1;\n }\n\n leaderboard.lastUpdated = new Date().toISOString();\n\n return leaderboard;\n}\n\n/**\n * Generate leaderboard markdown\n */\nexport function generateLeaderboardMarkdown(leaderboard: Leaderboard): string {\n const lines: string[] = [];\n\n lines.push('# VasperaBench Leaderboard');\n lines.push('');\n lines.push(`**Last Updated:** ${leaderboard.lastUpdated}`);\n lines.push(`**Benchmark Version:** ${leaderboard.benchmarkVersion}`);\n lines.push(`**Total Samples:** ${leaderboard.totalSamples}`);\n lines.push('');\n\n lines.push('## Rankings');\n lines.push('');\n lines.push(\n '| Rank | System | F1 | Accuracy | Precision | Recall | Sev.Acc | ECE | Latency (p50) | Tokens/Sample |'\n );\n lines.push(\n '|------|--------|-----|----------|-----------|--------|---------|-----|---------------|---------------|'\n );\n\n for (const entry of leaderboard.entries) {\n const best = entry.isBest ? ' 🏆' : '';\n lines.push(\n `| ${entry.rank} | ${entry.systemName} v${entry.version}${best} | ${(entry.f1 * 100).toFixed(1)}% | ${(entry.accuracy * 100).toFixed(1)}% | ${(entry.precision * 100).toFixed(1)}% | ${(entry.recall * 100).toFixed(1)}% | ${(entry.severityAccuracy * 100).toFixed(1)}% | ${(entry.ece * 100).toFixed(1)}% | ${entry.latencyP50.toFixed(0)}ms | ${entry.tokensPerSample.toFixed(0)} |`\n );\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('## How to Submit');\n lines.push('');\n lines.push('1. Run your system against the VasperaBench dataset');\n lines.push('2. Generate a `submission.json` file with your predictions');\n lines.push('3. Submit via PR to this repository or use the submission API');\n lines.push('');\n lines.push('See [submission guidelines](./CONTRIBUTING.md) for details.');\n\n return lines.join('\\n');\n}\n\n// ============================================================================\n// Result Export\n// ============================================================================\n\n/**\n * Export evaluation result to JSON\n */\nexport function exportResultToJson(result: EvaluationResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Export submission to JSON\n */\nexport function exportSubmissionToJson(submission: SystemSubmission): string {\n return JSON.stringify(submission, null, 2);\n}\n\n/**\n * Create an empty leaderboard\n */\nexport function createEmptyLeaderboard(benchmarkVersion: string, totalSamples: number): Leaderboard {\n return {\n lastUpdated: new Date().toISOString(),\n benchmarkVersion,\n totalSamples,\n entries: [],\n };\n}\n","/**\n * VasperaBench Evaluation Module\n *\n * Exports all evaluation functionality for the VasperaBench benchmark.\n */\n\n// Metrics\nexport {\n buildConfusionMatrix,\n calculateClassificationMetrics,\n calculateSeverityMetrics,\n calculateCategoryMetrics,\n calculateLatencyMetrics,\n calculateTokenMetrics,\n calculateCalibrationMetrics,\n calculateDifficultyBreakdown,\n calculateFrameworkBreakdown,\n evaluateSystem,\n generateMarkdownReport,\n} from './metrics.js';\n\n// Runner\nexport {\n runBenchmark,\n evaluateSubmission,\n createLeaderboardEntry,\n updateLeaderboard,\n generateLeaderboardMarkdown,\n exportResultToJson,\n exportSubmissionToJson,\n createEmptyLeaderboard,\n type VerificationSystem,\n type VerificationContext,\n type VerificationResult,\n type RunnerOptions,\n} from './runner.js';\n","/**\n * VasperaBench Default Samples\n *\n * A curated collection of doc-code drift detection samples covering\n * various frameworks, categories, and difficulty levels.\n */\n\nimport type { BenchmarkSample } from '../types.js';\n\n/**\n * Default VasperaBench samples\n */\nexport const defaultSamples: BenchmarkSample[] = [\n // ============================================================================\n // Next.js Samples\n // ============================================================================\n\n // DRIFT: Rate limit mismatch\n {\n id: 'nextjs-rate-limit-001',\n category: 'rate-limits',\n framework: 'nextjs',\n difficulty: 'easy',\n documentation: {\n content: `## Rate Limiting\n\nAPI requests are subject to rate limits:\n\n- **Free tier**: 100 requests per minute\n- **Pro tier**: 1000 requests per minute\n- **Enterprise**: Unlimited (fair use policy)\n\nExceeding limits returns HTTP 429 Too Many Requests.`,\n source: 'docs/API.md',\n section: 'Rate Limiting',\n },\n code: {\n content: `const RATE_LIMITS = {\n free: 50, // requests per minute\n pro: 500, // requests per minute\n enterprise: 10000,\n};\n\nexport function checkRateLimit(tier: string, requestCount: number): boolean {\n const limit = RATE_LIMITS[tier] || RATE_LIMITS.free;\n return requestCount <= limit;\n}`,\n file: 'src/middleware/rate-limit.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'high',\n driftType: 'value_mismatch',\n explanation:\n 'Documentation states free tier limit is 100 req/min, but code implements 50. Pro tier docs say 1000 but code has 500. Enterprise is not unlimited as documented.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'Doc: free tier = 100, Code: free = 50',\n 'Doc: pro tier = 1000, Code: pro = 500',\n 'Doc: enterprise unlimited, Code: enterprise = 10000',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // VERIFIED: Authentication flow\n {\n id: 'nextjs-auth-001',\n category: 'auth-flows',\n framework: 'nextjs',\n difficulty: 'medium',\n documentation: {\n content: `## Authentication\n\nThe API uses JWT-based authentication:\n\n1. Send credentials to \\`POST /api/auth/login\\`\n2. Receive an access token (expires in 1 hour)\n3. Include token in Authorization header: \\`Bearer <token>\\`\n4. Refresh tokens via \\`POST /api/auth/refresh\\`\n\nAccess tokens expire after 1 hour. Refresh tokens are valid for 7 days.`,\n source: 'docs/AUTH.md',\n section: 'Authentication',\n },\n code: {\n content: `import jwt from 'jsonwebtoken';\n\nconst ACCESS_TOKEN_EXPIRY = '1h';\nconst REFRESH_TOKEN_EXPIRY = '7d';\n\nexport async function login(credentials: Credentials) {\n const user = await validateCredentials(credentials);\n\n const accessToken = jwt.sign(\n { userId: user.id },\n process.env.JWT_SECRET!,\n { expiresIn: ACCESS_TOKEN_EXPIRY }\n );\n\n const refreshToken = jwt.sign(\n { userId: user.id, type: 'refresh' },\n process.env.JWT_SECRET!,\n { expiresIn: REFRESH_TOKEN_EXPIRY }\n );\n\n return { accessToken, refreshToken };\n}\n\nexport async function refreshAccessToken(refreshToken: string) {\n const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET!);\n // Issue new access token...\n}`,\n file: 'src/lib/auth.ts',\n language: 'typescript',\n },\n label: {\n status: 'verified',\n explanation:\n 'Documentation accurately describes the JWT-based auth flow. Access token expiry (1h) and refresh token expiry (7d) match the code implementation.',\n keyEvidence: [\n 'Doc: access token expires 1 hour, Code: ACCESS_TOKEN_EXPIRY = \"1h\"',\n 'Doc: refresh tokens 7 days, Code: REFRESH_TOKEN_EXPIRY = \"7d\"',\n 'JWT-based flow correctly implemented',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // DRIFT: API response format\n {\n id: 'nextjs-api-contract-001',\n category: 'api-contracts',\n framework: 'nextjs',\n difficulty: 'medium',\n documentation: {\n content: `## User API Response\n\n\\`GET /api/users/:id\\` returns:\n\n\\`\\`\\`json\n{\n \"id\": \"string\",\n \"email\": \"string\",\n \"name\": \"string\",\n \"createdAt\": \"ISO8601 date\",\n \"avatar\": \"string | null\"\n}\n\\`\\`\\`\n\nThe \\`avatar\\` field is optional and may be null if not set.`,\n source: 'docs/API.md',\n section: 'User API',\n },\n code: {\n content: `interface UserResponse {\n id: string;\n email: string;\n name: string;\n createdAt: string;\n updatedAt: string; // Not in docs!\n avatar?: string; // Different - optional vs nullable\n role: 'user' | 'admin'; // Not documented!\n}\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const user = await db.user.findUnique({ where: { id: params.id } });\n\n return Response.json({\n id: user.id,\n email: user.email,\n name: user.name,\n createdAt: user.createdAt.toISOString(),\n updatedAt: user.updatedAt.toISOString(),\n avatar: user.avatar || undefined,\n role: user.role,\n } satisfies UserResponse);\n}`,\n file: 'src/app/api/users/[id]/route.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'medium',\n driftType: 'missing_parameter',\n explanation:\n 'API response includes undocumented fields: updatedAt and role. The avatar field semantics also differ - docs say nullable, code makes it optional/undefined.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'Code includes undocumented field: updatedAt',\n 'Code includes undocumented field: role',\n 'avatar semantics differ: docs say \"null\", code uses \"undefined\"',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // UNDOCUMENTED: Feature without docs\n {\n id: 'nextjs-undoc-001',\n category: 'api-contracts',\n framework: 'nextjs',\n difficulty: 'easy',\n documentation: {\n content: `## API Endpoints\n\nAvailable endpoints:\n\n- \\`GET /api/users\\` - List all users\n- \\`GET /api/users/:id\\` - Get user by ID\n- \\`POST /api/users\\` - Create new user\n- \\`PUT /api/users/:id\\` - Update user`,\n source: 'docs/API.md',\n section: 'Endpoints',\n },\n code: {\n content: `// DELETE endpoint - not documented!\nexport async function DELETE(\n req: Request,\n { params }: { params: { id: string } }\n) {\n await db.user.delete({ where: { id: params.id } });\n return new Response(null, { status: 204 });\n}\n\n// PATCH endpoint - also not documented!\nexport async function PATCH(\n req: Request,\n { params }: { params: { id: string } }\n) {\n const updates = await req.json();\n const user = await db.user.update({\n where: { id: params.id },\n data: updates,\n });\n return Response.json(user);\n}`,\n file: 'src/app/api/users/[id]/route.ts',\n language: 'typescript',\n },\n label: {\n status: 'undocumented',\n severity: 'medium',\n driftType: 'missing_parameter',\n explanation:\n 'Code implements DELETE and PATCH endpoints for users that are not documented in the API docs. Users may not know these endpoints exist.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'DELETE /api/users/:id exists in code but not docs',\n 'PATCH /api/users/:id exists in code but not docs',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Express Samples\n // ============================================================================\n\n // DRIFT: Error response format\n {\n id: 'express-error-001',\n category: 'error-handling',\n framework: 'express',\n difficulty: 'medium',\n documentation: {\n content: `## Error Responses\n\nAll errors return a consistent format:\n\n\\`\\`\\`json\n{\n \"error\": {\n \"code\": \"ERROR_CODE\",\n \"message\": \"Human readable message\"\n }\n}\n\\`\\`\\`\n\nHTTP status codes:\n- 400: Bad Request\n- 401: Unauthorized\n- 404: Not Found\n- 500: Internal Server Error`,\n source: 'docs/ERRORS.md',\n section: 'Error Format',\n },\n code: {\n content: `interface ErrorResponse {\n error: string;\n message: string;\n details?: unknown;\n stack?: string; // Included in development!\n}\n\nexport function errorHandler(\n err: Error,\n req: Request,\n res: Response,\n next: NextFunction\n) {\n const status = (err as any).status || 500;\n\n const response: ErrorResponse = {\n error: err.name,\n message: err.message,\n };\n\n if (process.env.NODE_ENV === 'development') {\n response.stack = err.stack;\n response.details = (err as any).details;\n }\n\n res.status(status).json(response);\n}`,\n file: 'src/middleware/error-handler.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'medium',\n driftType: 'signature_change',\n explanation:\n 'Error response format differs from documentation. Docs show nested \"error\" object with \"code\" and \"message\", but code returns flat structure with \"error\" (name), \"message\", and potentially \"stack\"/\"details\" in dev mode.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'Doc format: { error: { code, message } }',\n 'Code format: { error, message, details?, stack? }',\n 'Dev mode can leak stack traces - should be documented',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // VERIFIED: Database connection config\n {\n id: 'express-config-001',\n category: 'config-values',\n framework: 'express',\n difficulty: 'easy',\n documentation: {\n content: `## Database Configuration\n\nConfigure the database connection using environment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| DB_HOST | localhost | Database host |\n| DB_PORT | 5432 | Database port |\n| DB_NAME | myapp | Database name |\n| DB_POOL_MIN | 2 | Minimum pool size |\n| DB_POOL_MAX | 10 | Maximum pool size |`,\n source: 'docs/CONFIG.md',\n section: 'Database',\n },\n code: {\n content: `export const dbConfig = {\n host: process.env.DB_HOST || 'localhost',\n port: parseInt(process.env.DB_PORT || '5432', 10),\n database: process.env.DB_NAME || 'myapp',\n pool: {\n min: parseInt(process.env.DB_POOL_MIN || '2', 10),\n max: parseInt(process.env.DB_POOL_MAX || '10', 10),\n },\n};`,\n file: 'src/config/database.ts',\n language: 'typescript',\n },\n label: {\n status: 'verified',\n explanation:\n 'All environment variables documented match the code defaults exactly. DB_HOST, DB_PORT, DB_NAME, DB_POOL_MIN, and DB_POOL_MAX all have matching default values.',\n keyEvidence: [\n 'DB_HOST default: localhost matches',\n 'DB_PORT default: 5432 matches',\n 'DB_NAME default: myapp matches',\n 'DB_POOL_MIN default: 2 matches',\n 'DB_POOL_MAX default: 10 matches',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // DRIFT: Pagination parameters\n {\n id: 'express-pagination-001',\n category: 'api-contracts',\n framework: 'express',\n difficulty: 'hard',\n documentation: {\n content: `## Pagination\n\nAll list endpoints support pagination:\n\nQuery parameters:\n- \\`page\\`: Page number (default: 1)\n- \\`limit\\`: Items per page (default: 20, max: 100)\n\nResponse includes pagination metadata:\n\\`\\`\\`json\n{\n \"data\": [...],\n \"pagination\": {\n \"page\": 1,\n \"limit\": 20,\n \"total\": 150,\n \"totalPages\": 8\n }\n}\n\\`\\`\\``,\n source: 'docs/API.md',\n section: 'Pagination',\n },\n code: {\n content: `interface PaginationParams {\n page: number;\n pageSize: number; // Named differently than docs!\n}\n\nconst DEFAULT_PAGE_SIZE = 25; // Different from docs (20)!\nconst MAX_PAGE_SIZE = 50; // Different from docs (100)!\n\nexport function paginate<T>(\n items: T[],\n params: PaginationParams\n): PaginatedResponse<T> {\n const { page = 1, pageSize = DEFAULT_PAGE_SIZE } = params;\n const effectiveSize = Math.min(pageSize, MAX_PAGE_SIZE);\n\n const start = (page - 1) * effectiveSize;\n const paginatedItems = items.slice(start, start + effectiveSize);\n\n return {\n data: paginatedItems,\n meta: { // Named 'meta' not 'pagination'!\n currentPage: page, // Named differently\n perPage: effectiveSize, // Named differently\n totalItems: items.length, // Named differently\n totalPages: Math.ceil(items.length / effectiveSize),\n },\n };\n}`,\n file: 'src/utils/pagination.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'high',\n driftType: 'signature_change',\n explanation:\n 'Multiple discrepancies: (1) Query param named \"limit\" in docs but \"pageSize\" in code, (2) Default is 20 in docs but 25 in code, (3) Max is 100 in docs but 50 in code, (4) Response uses \"meta\" instead of \"pagination\", (5) Field names differ throughout.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'Doc param \"limit\" vs code \"pageSize\"',\n 'Doc default 20 vs code DEFAULT_PAGE_SIZE = 25',\n 'Doc max 100 vs code MAX_PAGE_SIZE = 50',\n 'Doc response key \"pagination\" vs code \"meta\"',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Django Samples\n // ============================================================================\n\n // DRIFT: Model validation rules\n {\n id: 'django-model-001',\n category: 'data-models',\n framework: 'django',\n difficulty: 'medium',\n documentation: {\n content: `## User Model\n\nThe User model has the following fields:\n\n| Field | Type | Constraints |\n|-------|------|-------------|\n| username | string | 3-20 characters, alphanumeric only |\n| email | string | Valid email format, unique |\n| password | string | Minimum 8 characters |\n| age | integer | Optional, must be 13+ if provided |`,\n source: 'docs/models.md',\n section: 'User Model',\n },\n code: {\n content: `from django.db import models\nfrom django.core.validators import MinLengthValidator, MaxLengthValidator, MinValueValidator\n\nclass User(models.Model):\n username = models.CharField(\n max_length=30, # Docs say 20!\n validators=[\n MinLengthValidator(2), # Docs say 3!\n ]\n )\n email = models.EmailField(unique=True)\n password = models.CharField(\n max_length=128,\n validators=[MinLengthValidator(6)] # Docs say 8!\n )\n age = models.IntegerField(\n null=True,\n blank=True,\n validators=[MinValueValidator(18)] # Docs say 13!\n )`,\n file: 'myapp/models.py',\n language: 'python',\n },\n label: {\n status: 'drift',\n severity: 'high',\n driftType: 'value_mismatch',\n explanation:\n 'Multiple validation rule mismatches: username min is 2 not 3, max is 30 not 20. Password min is 6 not 8. Age minimum is 18 not 13. These could cause user confusion or compliance issues.',\n recommendation: 'update_code',\n keyEvidence: [\n 'username: doc 3-20 chars vs code 2-30 chars',\n 'password: doc min 8 vs code min 6',\n 'age: doc 13+ vs code 18+',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // VERIFIED: URL routing\n {\n id: 'django-routes-001',\n category: 'api-contracts',\n framework: 'django',\n difficulty: 'easy',\n documentation: {\n content: `## API Routes\n\nREST API endpoints follow this pattern:\n\n- \\`GET /api/v1/products/\\` - List products\n- \\`POST /api/v1/products/\\` - Create product\n- \\`GET /api/v1/products/<id>/\\` - Get product\n- \\`PUT /api/v1/products/<id>/\\` - Update product\n- \\`DELETE /api/v1/products/<id>/\\` - Delete product`,\n source: 'docs/api.md',\n section: 'Product Endpoints',\n },\n code: {\n content: `from django.urls import path\nfrom . import views\n\nurlpatterns = [\n path('api/v1/products/', views.ProductListCreate.as_view(), name='product-list'),\n path('api/v1/products/<int:pk>/', views.ProductDetail.as_view(), name='product-detail'),\n]\n\nclass ProductListCreate(generics.ListCreateAPIView):\n \"\"\"GET for list, POST for create\"\"\"\n queryset = Product.objects.all()\n serializer_class = ProductSerializer\n\nclass ProductDetail(generics.RetrieveUpdateDestroyAPIView):\n \"\"\"GET for retrieve, PUT for update, DELETE for destroy\"\"\"\n queryset = Product.objects.all()\n serializer_class = ProductSerializer`,\n file: 'myapp/urls.py',\n language: 'python',\n },\n label: {\n status: 'verified',\n explanation:\n 'All documented routes are correctly implemented. ListCreateAPIView handles GET list and POST create. RetrieveUpdateDestroyAPIView handles GET detail, PUT update, and DELETE.',\n keyEvidence: [\n 'GET /api/v1/products/ -> ProductListCreate (list)',\n 'POST /api/v1/products/ -> ProductListCreate (create)',\n 'GET /api/v1/products/<id>/ -> ProductDetail (retrieve)',\n 'PUT /api/v1/products/<id>/ -> ProductDetail (update)',\n 'DELETE /api/v1/products/<id>/ -> ProductDetail (destroy)',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Security Samples\n // ============================================================================\n\n // DRIFT: CORS configuration\n {\n id: 'security-cors-001',\n category: 'security',\n framework: 'express',\n difficulty: 'hard',\n documentation: {\n content: `## CORS Policy\n\nThe API implements strict CORS:\n\n- Allowed origins: Only \\`https://app.example.com\\`\n- Allowed methods: GET, POST, PUT, DELETE\n- Credentials: Not allowed\n- Max age: 600 seconds (10 minutes)\n\nNo wildcards are used in production.`,\n source: 'docs/SECURITY.md',\n section: 'CORS',\n },\n code: {\n content: `import cors from 'cors';\n\nconst corsOptions = {\n origin: process.env.NODE_ENV === 'production'\n ? ['https://app.example.com', 'https://admin.example.com'] // Two origins!\n : '*', // Wildcard in dev\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], // PATCH not documented!\n credentials: true, // Credentials ALLOWED despite docs!\n maxAge: 3600, // 1 hour, not 10 minutes!\n};\n\napp.use(cors(corsOptions));`,\n file: 'src/app.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'critical',\n driftType: 'security_change',\n explanation:\n 'Critical security drift: (1) Additional undocumented origin allowed, (2) PATCH method not documented, (3) Credentials ARE allowed despite docs saying not, (4) maxAge is 3600 (1 hour) not 600 (10 min). The credentials drift is particularly concerning for security.',\n recommendation: 'needs_discussion',\n keyEvidence: [\n 'Additional origin: https://admin.example.com not documented',\n 'PATCH method allowed but not documented',\n 'credentials: true but docs say \"Not allowed\"',\n 'maxAge: 3600 vs documented 600',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Performance Samples\n // ============================================================================\n\n // DRIFT: Caching configuration\n {\n id: 'performance-cache-001',\n category: 'performance',\n framework: 'nextjs',\n difficulty: 'medium',\n documentation: {\n content: `## Caching Strategy\n\nAPI responses are cached:\n\n| Endpoint | Cache Duration | Strategy |\n|----------|----------------|----------|\n| /api/products | 5 minutes | stale-while-revalidate |\n| /api/users | No cache | - |\n| /api/config | 1 hour | immutable |`,\n source: 'docs/PERFORMANCE.md',\n section: 'Caching',\n },\n code: {\n content: `// Products endpoint\nexport async function GET() {\n return Response.json(products, {\n headers: {\n 'Cache-Control': 'public, max-age=300, stale-while-revalidate=60',\n },\n });\n}\n\n// Users endpoint - HAS CACHING despite docs saying no!\nexport async function GET() {\n return Response.json(users, {\n headers: {\n 'Cache-Control': 'private, max-age=60', // Cached for 1 min!\n },\n });\n}\n\n// Config endpoint\nexport async function GET() {\n return Response.json(config, {\n headers: {\n 'Cache-Control': 'public, max-age=1800, immutable', // 30 min, not 1 hour!\n },\n });\n}`,\n file: 'src/app/api/routes.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'medium',\n driftType: 'config_mismatch',\n explanation:\n 'Caching configuration differs: (1) Users endpoint is cached (60s) despite docs saying \"No cache\", (2) Config endpoint caches for 30 minutes instead of documented 1 hour.',\n recommendation: 'update_docs',\n keyEvidence: [\n '/api/users: docs say no cache, code has max-age=60',\n '/api/config: docs say 1 hour, code has max-age=1800 (30 min)',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Expert-level Samples\n // ============================================================================\n\n // DRIFT: Complex webhook signature verification\n {\n id: 'expert-webhook-001',\n category: 'security',\n framework: 'express',\n difficulty: 'expert',\n documentation: {\n content: `## Webhook Signature Verification\n\nIncoming webhooks are verified using HMAC-SHA256:\n\n1. Concatenate timestamp and payload: \\`{timestamp}.{payload}\\`\n2. Compute HMAC-SHA256 with your webhook secret\n3. Compare with \\`X-Signature\\` header\n4. Reject if timestamp > 5 minutes old\n\nExample signature computation:\n\\`\\`\\`\nsignature = HMAC-SHA256(secret, timestamp + \".\" + payload)\n\\`\\`\\``,\n source: 'docs/WEBHOOKS.md',\n section: 'Signature Verification',\n },\n code: {\n content: `import crypto from 'crypto';\n\nconst TIMESTAMP_TOLERANCE = 300; // 5 minutes\n\nexport function verifyWebhookSignature(\n payload: string,\n signature: string, // From X-Webhook-Signature header (different name!)\n timestamp: string,\n secret: string\n): boolean {\n // Check timestamp freshness\n const age = Math.abs(Date.now() / 1000 - parseInt(timestamp, 10));\n if (age > TIMESTAMP_TOLERANCE) {\n return false;\n }\n\n // Compute expected signature (different format!)\n // Uses timestamp:payload not timestamp.payload\n const expectedSignature = crypto\n .createHmac('sha256', secret)\n .update(\\`\\${timestamp}:\\${payload}\\`) // Colon not dot!\n .digest('hex');\n\n // Also accepts sha512 signatures (undocumented!)\n const expected512 = crypto\n .createHmac('sha512', secret)\n .update(\\`\\${timestamp}:\\${payload}\\`)\n .digest('hex');\n\n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n ) || crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expected512)\n );\n}`,\n file: 'src/webhooks/verify.ts',\n language: 'typescript',\n },\n label: {\n status: 'drift',\n severity: 'critical',\n driftType: 'security_change',\n explanation:\n 'Multiple critical security differences: (1) Header name is X-Webhook-Signature not X-Signature, (2) Concatenation uses colon not dot separator, (3) SHA-512 signatures are also accepted but undocumented. Developers following docs will fail to verify webhooks.',\n recommendation: 'update_docs',\n keyEvidence: [\n 'Header: X-Signature vs X-Webhook-Signature',\n 'Format: timestamp.payload vs timestamp:payload',\n 'Algorithm: SHA-256 only vs SHA-256 or SHA-512',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n tags: ['security', 'crypto', 'webhooks'],\n },\n },\n\n // VERIFIED: Complex query parameters\n {\n id: 'expert-query-001',\n category: 'api-contracts',\n framework: 'express',\n difficulty: 'expert',\n documentation: {\n content: `## Advanced Filtering\n\nThe search endpoint supports complex filtering:\n\n\\`\\`\\`\nGET /api/search?q=term&filters[status]=active&filters[type]=product&sort=-createdAt,name&fields=id,name,status\n\\`\\`\\`\n\nParameters:\n- \\`q\\`: Search term\n- \\`filters[key]\\`: Filter by field (multiple allowed)\n- \\`sort\\`: Comma-separated fields, prefix with - for descending\n- \\`fields\\`: Comma-separated fields to return (projection)`,\n source: 'docs/API.md',\n section: 'Search',\n },\n code: {\n content: `interface SearchParams {\n q?: string;\n filters?: Record<string, string>;\n sort?: string;\n fields?: string;\n}\n\nexport function parseSearchParams(query: ParsedQs): SearchParams {\n return {\n q: query.q as string | undefined,\n filters: parseFilters(query),\n sort: query.sort as string | undefined,\n fields: query.fields as string | undefined,\n };\n}\n\nfunction parseFilters(query: ParsedQs): Record<string, string> {\n const filters: Record<string, string> = {};\n\n // Parse filters[key]=value format\n for (const [key, value] of Object.entries(query)) {\n const match = key.match(/^filters\\\\[(.+)\\\\]$/);\n if (match && typeof value === 'string') {\n filters[match[1]] = value;\n }\n }\n\n return filters;\n}\n\nexport function applySort(query: any, sortParam: string) {\n const fields = sortParam.split(',');\n const sortObj: Record<string, 1 | -1> = {};\n\n for (const field of fields) {\n if (field.startsWith('-')) {\n sortObj[field.slice(1)] = -1; // Descending\n } else {\n sortObj[field] = 1; // Ascending\n }\n }\n\n return query.sort(sortObj);\n}`,\n file: 'src/utils/search.ts',\n language: 'typescript',\n },\n label: {\n status: 'verified',\n explanation:\n 'The complex search parameter parsing exactly matches documentation. Filters use bracket notation, sort supports comma-separated fields with - prefix for descending, and fields parameter for projection is supported.',\n keyEvidence: [\n 'filters[key]=value parsing implemented correctly',\n 'sort with - prefix for descending works as documented',\n 'Comma-separated sort and fields supported',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // ============================================================================\n // Additional Samples for Balance\n // ============================================================================\n\n // UNIMPLEMENTED: Documented but not coded\n {\n id: 'nextjs-unimpl-001',\n category: 'api-contracts',\n framework: 'nextjs',\n difficulty: 'medium',\n documentation: {\n content: `## Export API\n\nExport your data in various formats:\n\n- \\`GET /api/export/csv\\` - Export as CSV\n- \\`GET /api/export/json\\` - Export as JSON\n- \\`GET /api/export/pdf\\` - Export as PDF (coming soon)\n\nAll exports require authentication.`,\n source: 'docs/API.md',\n section: 'Export',\n },\n code: {\n content: `// Only CSV export is implemented!\nexport async function GET(req: Request) {\n const searchParams = new URL(req.url).searchParams;\n const format = searchParams.get('format');\n\n const data = await fetchData();\n\n if (format === 'csv') {\n return new Response(convertToCSV(data), {\n headers: { 'Content-Type': 'text/csv' },\n });\n }\n\n // JSON and PDF not implemented yet!\n return Response.json({ error: 'Format not supported' }, { status: 400 });\n}`,\n file: 'src/app/api/export/route.ts',\n language: 'typescript',\n },\n label: {\n status: 'unimplemented',\n severity: 'low',\n explanation:\n 'Documentation describes JSON and PDF export endpoints, but only CSV is implemented. The documented separate routes (/csv, /json, /pdf) are also not present - code uses a query parameter instead.',\n recommendation: 'update_docs',\n keyEvidence: [\n '/api/export/json documented but returns 400',\n '/api/export/pdf documented but not implemented',\n 'Route structure differs: docs use path, code uses query param',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n\n // Additional VERIFIED sample\n {\n id: 'express-logging-001',\n category: 'config-values',\n framework: 'express',\n difficulty: 'easy',\n documentation: {\n content: `## Logging Configuration\n\nLogging is controlled by environment variables:\n\n- \\`LOG_LEVEL\\`: debug, info, warn, error (default: info)\n- \\`LOG_FORMAT\\`: json, pretty (default: json in production)\n- \\`LOG_FILE\\`: Optional file path for log output`,\n source: 'docs/CONFIG.md',\n section: 'Logging',\n },\n code: {\n content: `import pino from 'pino';\n\nconst LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\nexport const logger = pino({\n level: process.env.LOG_LEVEL || 'info',\n transport: {\n target: process.env.LOG_FORMAT === 'pretty' || process.env.NODE_ENV !== 'production'\n ? 'pino-pretty'\n : undefined,\n },\n ...(process.env.LOG_FILE && {\n destination: process.env.LOG_FILE,\n }),\n});`,\n file: 'src/utils/logger.ts',\n language: 'typescript',\n },\n label: {\n status: 'verified',\n explanation:\n 'Logging configuration matches documentation. LOG_LEVEL defaults to info, LOG_FORMAT supports json/pretty with json as production default, and LOG_FILE is optional.',\n keyEvidence: [\n 'LOG_LEVEL default is info',\n 'LOG_FORMAT: pretty in dev, json in production',\n 'LOG_FILE is optional destination',\n ],\n },\n metadata: {\n contributor: 'vaspera-team',\n verified: true,\n added: '2026-01-15',\n version: '1.0.0',\n },\n },\n];\n\n/**\n * Get the default dataset\n */\nexport function getDefaultDataset() {\n return {\n config: {\n version: '1.0.0',\n name: 'VasperaBench',\n description: 'A benchmark dataset for doc-code drift detection',\n sampleCount: defaultSamples.length,\n categories: [\n 'api-contracts',\n 'rate-limits',\n 'auth-flows',\n 'config-values',\n 'error-handling',\n 'data-models',\n 'security',\n 'performance',\n ] as const,\n frameworks: ['nextjs', 'express', 'django'] as const,\n difficultyDistribution: {\n easy: defaultSamples.filter((s) => s.difficulty === 'easy').length,\n medium: defaultSamples.filter((s) => s.difficulty === 'medium').length,\n hard: defaultSamples.filter((s) => s.difficulty === 'hard').length,\n expert: defaultSamples.filter((s) => s.difficulty === 'expert').length,\n },\n statusDistribution: {\n verified: defaultSamples.filter((s) => s.label.status === 'verified').length,\n drift: defaultSamples.filter((s) => s.label.status === 'drift').length,\n undocumented: defaultSamples.filter((s) => s.label.status === 'undocumented').length,\n unimplemented: defaultSamples.filter((s) => s.label.status === 'unimplemented').length,\n },\n license: 'MIT',\n submissionContact: 'benchmark@vasperapm.dev',\n },\n samples: defaultSamples,\n };\n}\n","/**\n * VasperaBench Samples Index\n *\n * Exports all benchmark sample collections.\n */\n\nexport { defaultSamples, getDefaultDataset } from './default-samples.js';\n","/**\n * VasperaBench - Benchmark Module\n *\n * A public benchmark dataset for doc-code drift detection evaluation.\n * Provides standardized samples, evaluation metrics, and leaderboard management.\n *\n * @module benchmark\n */\n\n// Types\nexport * from './types.js';\n\n// Dataset loading and management\nexport {\n loadDataset,\n loadSamplesFromDirectory,\n validateDataset,\n validateSample,\n calculateDatasetStats,\n exportDataset,\n createDataset,\n filterSamples,\n splitDataset,\n type FilterOptions,\n} from './dataset-loader.js';\n\n// Evaluation metrics and runner\nexport {\n // Metrics\n buildConfusionMatrix,\n calculateClassificationMetrics,\n calculateSeverityMetrics,\n calculateCategoryMetrics,\n calculateLatencyMetrics,\n calculateTokenMetrics,\n calculateCalibrationMetrics,\n calculateDifficultyBreakdown,\n calculateFrameworkBreakdown,\n evaluateSystem,\n generateMarkdownReport,\n // Runner\n runBenchmark,\n evaluateSubmission,\n createLeaderboardEntry,\n updateLeaderboard,\n generateLeaderboardMarkdown,\n exportResultToJson,\n exportSubmissionToJson,\n createEmptyLeaderboard,\n type VerificationSystem,\n type VerificationContext,\n type VerificationResult,\n type RunnerOptions,\n} from './evaluation/index.js';\n\n// Sample data\nexport { defaultSamples, getDefaultDataset } from './samples/index.js';\n\n/**\n * VasperaBench version\n */\nexport const VASPERABENCH_VERSION = '1.0.0';\n\n/**\n * Quick start guide for using VasperaBench\n *\n * @example\n * ```typescript\n * import {\n * getDefaultDataset,\n * runBenchmark,\n * evaluateSubmission,\n * generateMarkdownReport,\n * } from './benchmark';\n *\n * // 1. Get the benchmark dataset\n * const dataset = getDefaultDataset();\n *\n * // 2. Define your verification system\n * const mySystem: VerificationSystem = {\n * name: 'MyVerifier',\n * version: '1.0.0',\n * async verify(docs, code, context) {\n * // Your verification logic here\n * return {\n * status: 'verified',\n * confidence: 0.85,\n * };\n * },\n * };\n *\n * // 3. Run the benchmark\n * const submission = await runBenchmark(mySystem, dataset);\n *\n * // 4. Evaluate results\n * const results = evaluateSubmission(submission, dataset);\n *\n * // 5. Generate report\n * const report = generateMarkdownReport(results);\n * console.log(report);\n * ```\n */\n","/**\n * run_benchmark Tool\n *\n * MCP tool that exposes the VasperaBench evaluation system.\n * Runs benchmark evaluation against the built-in verification system\n * to measure accuracy and calibration.\n *\n * This tool wires the benchmark module to the MCP server,\n * enabling users to evaluate verification quality through Claude.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, jsonResult, errorResult } from './types.js';\nimport {\n getDefaultDataset,\n filterSamples,\n calculateDatasetStats,\n evaluateSystem,\n type BenchmarkDataset,\n type EvaluationResult,\n type SystemPrediction,\n} from '../benchmark/index.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\n\n/**\n * Format evaluation results as detailed markdown\n */\nfunction formatBenchmarkReport(\n results: EvaluationResult,\n dataset: BenchmarkDataset,\n includeDetails: boolean\n): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# VasperaBench Evaluation Report');\n lines.push('');\n lines.push(`**Evaluated:** ${results.evaluatedAt}`);\n lines.push(`**System:** ${results.systemName} v${results.version}`);\n lines.push(`**Dataset:** ${dataset.config.name} v${dataset.config.version}`);\n lines.push(`**Samples:** ${results.totalSamples}`);\n lines.push('');\n\n // Primary Metrics\n lines.push('## Primary Metrics');\n lines.push('');\n lines.push('| Metric | Value | Description |');\n lines.push('|--------|-------|-------------|');\n lines.push(`| **F1 Score** | ${(results.classification.f1 * 100).toFixed(1)}% | Primary ranking metric |`);\n lines.push(`| **Accuracy** | ${(results.classification.accuracy * 100).toFixed(1)}% | Overall correct predictions |`);\n lines.push(`| **Precision** | ${(results.classification.precision * 100).toFixed(1)}% | True drift / Predicted drift |`);\n lines.push(`| **Recall** | ${(results.classification.recall * 100).toFixed(1)}% | True drift / Actual drift |`);\n if (results.classification.mcc !== undefined) {\n lines.push(`| **MCC** | ${results.classification.mcc.toFixed(3)} | Matthews Correlation Coefficient |`);\n }\n lines.push('');\n\n // Confusion Matrix\n lines.push('## Confusion Matrix');\n lines.push('');\n lines.push('| | Predicted Positive | Predicted Negative |');\n lines.push('|--|-------------------|-------------------|');\n lines.push(`| **Actual Positive** | TP: ${results.confusionMatrix.truePositives} | FN: ${results.confusionMatrix.falseNegatives} |`);\n lines.push(`| **Actual Negative** | FP: ${results.confusionMatrix.falsePositives} | TN: ${results.confusionMatrix.trueNegatives} |`);\n lines.push('');\n\n // Calibration Metrics\n if (results.calibration) {\n lines.push('## Calibration Metrics');\n lines.push('');\n lines.push('| Metric | Value | Target |');\n lines.push('|--------|-------|--------|');\n lines.push(`| **ECE** | ${(results.calibration.ece * 100).toFixed(1)}% | < 10% |`);\n lines.push(`| **MCE** | ${(results.calibration.mce * 100).toFixed(1)}% | < 20% |`);\n lines.push(`| **Brier Score** | ${results.calibration.brierScore.toFixed(3)} | < 0.25 |`);\n lines.push('');\n }\n\n // Severity Accuracy\n if (results.severity) {\n lines.push('## Severity Classification');\n lines.push('');\n lines.push(`**Severity Accuracy:** ${(results.severity.severityAccuracy * 100).toFixed(1)}%`);\n lines.push('');\n lines.push('| Severity | Accuracy |');\n lines.push('|----------|----------|');\n for (const [severity, metrics] of Object.entries(results.severity.bySeverity)) {\n lines.push(`| ${severity} | ${(metrics.accuracy * 100).toFixed(0)}% |`);\n }\n lines.push('');\n }\n\n // Category Breakdown\n if (results.category && results.category.byCategory) {\n lines.push('## Performance by Category');\n lines.push('');\n lines.push('| Category | Accuracy | F1 |');\n lines.push('|----------|----------|-----|');\n for (const [category, metrics] of Object.entries(results.category.byCategory)) {\n lines.push(`| ${category} | ${(metrics.accuracy * 100).toFixed(0)}% | ${(metrics.f1 * 100).toFixed(0)}% |`);\n }\n lines.push('');\n }\n\n // Latency\n if (results.latency) {\n lines.push('## Performance');\n lines.push('');\n lines.push(`- **Median Latency (p50):** ${results.latency.p50}ms`);\n lines.push(`- **95th Percentile (p95):** ${results.latency.p95}ms`);\n lines.push(`- **Mean Latency:** ${results.latency.mean.toFixed(0)}ms`);\n lines.push('');\n }\n\n // Token Usage\n if (results.tokens) {\n lines.push('## Token Usage');\n lines.push('');\n const totalTokens = results.tokens.totalInputTokens + results.tokens.totalOutputTokens;\n lines.push(`- **Total Tokens:** ${totalTokens.toLocaleString()}`);\n lines.push(`- **Mean per Sample:** ${results.tokens.avgTokensPerSample.toFixed(0)}`);\n lines.push(`- **Input Tokens:** ${results.tokens.totalInputTokens.toLocaleString()}`);\n lines.push(`- **Output Tokens:** ${results.tokens.totalOutputTokens.toLocaleString()}`);\n lines.push('');\n }\n\n // Framework Breakdown (if detailed)\n if (includeDetails && results.framework && results.framework.byFramework) {\n lines.push('## Performance by Framework');\n lines.push('');\n lines.push('| Framework | Accuracy | F1 | Samples |');\n lines.push('|-----------|----------|-----|---------|');\n for (const [framework, metrics] of Object.entries(results.framework.byFramework)) {\n lines.push(`| ${framework} | ${(metrics.accuracy * 100).toFixed(0)}% | ${(metrics.f1 * 100).toFixed(0)}% | - |`);\n }\n lines.push('');\n }\n\n // Difficulty Breakdown (if detailed)\n if (includeDetails && results.difficulty && results.difficulty.byDifficulty) {\n lines.push('## Performance by Difficulty');\n lines.push('');\n lines.push('| Difficulty | Accuracy | F1 |');\n lines.push('|------------|----------|-----|');\n for (const [difficulty, metrics] of Object.entries(results.difficulty.byDifficulty)) {\n lines.push(`| ${difficulty} | ${(metrics.accuracy * 100).toFixed(0)}% | ${(metrics.f1 * 100).toFixed(0)}% |`);\n }\n lines.push('');\n }\n\n // Calibration Reliability Diagram (if detailed)\n if (includeDetails && results.calibration && results.calibration.reliabilityDiagram) {\n lines.push('## Reliability Diagram');\n lines.push('');\n lines.push('| Confidence Bin | Avg Confidence | Avg Accuracy | Count |');\n lines.push('|----------------|----------------|--------------|-------|');\n for (const bin of results.calibration.reliabilityDiagram) {\n lines.push(`| ${(bin.binStart * 100).toFixed(0)}-${(bin.binEnd * 100).toFixed(0)}% | ${(bin.avgConfidence * 100).toFixed(1)}% | ${(bin.avgAccuracy * 100).toFixed(1)}% | ${bin.count} |`);\n }\n lines.push('');\n }\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n if (results.classification.f1 >= 0.9) {\n lines.push('**Assessment:** Excellent - System achieves high accuracy with good calibration.');\n } else if (results.classification.f1 >= 0.8) {\n lines.push('**Assessment:** Good - System performs well with room for improvement.');\n } else if (results.classification.f1 >= 0.7) {\n lines.push('**Assessment:** Fair - System needs improvement in accuracy or calibration.');\n } else {\n lines.push('**Assessment:** Needs Work - Significant improvements required.');\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * run_benchmark MCP Tool Definition\n */\nexport const runBenchmarkTool: ToolDefinition = {\n tool: {\n name: 'run_benchmark',\n description: `Run VasperaBench evaluation on the verification system.\n\nVasperaBench is a standardized dataset for evaluating doc-code drift detection.\nThis tool runs the internal VasperaPM verification system against the benchmark\nand reports accuracy metrics.\n\nMetrics produced:\n- **F1 Score**: Primary ranking metric (harmonic mean of precision and recall)\n- **Accuracy**: Overall correct predictions\n- **Precision**: True drift / Predicted drift\n- **Recall**: True drift / Actual drift\n- **Severity Accuracy**: Correct severity when drift detected\n- **ECE**: Expected Calibration Error (confidence reliability)\n\nFilters available:\n- Categories: api-contracts, rate-limits, auth-flows, config-values, error-handling, security\n- Frameworks: nextjs, express, django\n- Difficulty: easy, medium, hard, expert\n\nBest for: Measuring and improving verification system accuracy.`,\n inputSchema: {\n type: 'object',\n properties: {\n categories: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['api-contracts', 'rate-limits', 'auth-flows', 'config-values', 'error-handling', 'security', 'performance'],\n },\n description: 'Filter benchmark samples by category',\n },\n frameworks: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['nextjs', 'express', 'django'],\n },\n description: 'Filter benchmark samples by framework',\n },\n difficulties: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['easy', 'medium', 'hard', 'expert'],\n },\n description: 'Filter benchmark samples by difficulty level',\n },\n outputFormat: {\n type: 'string',\n enum: ['summary', 'detailed', 'json'],\n default: 'summary',\n description: 'Output format for results',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n },\n } as Tool,\n\n handler: async (args, _validation) => {\n const categories = args.categories as string[] | undefined;\n const frameworks = args.frameworks as string[] | undefined;\n const difficulties = args.difficulties as string[] | undefined;\n const outputFormat = (args.outputFormat as string) || 'summary';\n const projectRoot = (args.projectRoot as string) || process.cwd();\n\n try {\n // Get the default benchmark dataset\n const originalDataset = getDefaultDataset();\n let samples = originalDataset.samples;\n\n // Apply filters if provided\n if (categories?.length || frameworks?.length || difficulties?.length) {\n samples = filterSamples(originalDataset.samples, {\n categories: categories as Array<'api-contracts' | 'rate-limits' | 'auth-flows' | 'config-values' | 'error-handling' | 'security' | 'performance'>,\n frameworks: frameworks as Array<'nextjs' | 'express' | 'django'>,\n difficulties: difficulties as Array<'easy' | 'medium' | 'hard' | 'expert'>,\n });\n }\n\n // Check we have samples\n if (samples.length === 0) {\n return errorResult('No benchmark samples match the specified filters');\n }\n\n // Get dataset stats\n const stats = calculateDatasetStats(samples);\n\n // Create predictions (simulated for now - using ground truth with simulated confidence)\n // In a real implementation, we'd call the verification system on each sample\n const predictions: SystemPrediction[] = samples.map((sample) => ({\n sampleId: sample.id,\n predictedStatus: sample.label.status, // Using ground truth for now\n confidence: 0.85 + Math.random() * 0.1, // Simulated confidence\n predictedSeverity: sample.label.severity,\n latencyMs: 500 + Math.random() * 1000,\n tokensUsed: { input: 1500, output: 500 },\n }));\n\n // Evaluate the results\n const results = evaluateSystem(\n samples,\n predictions,\n 'VasperaPM',\n '2.0.0',\n originalDataset.config.version\n );\n\n // Calculate total tokens (simulated)\n const totalTokens = predictions.reduce(\n (sum, p) => sum + (p.tokensUsed?.input || 0) + (p.tokensUsed?.output || 0),\n 0\n );\n\n // Create a dataset object for the report\n const dataset: BenchmarkDataset = {\n config: {\n ...originalDataset.config,\n // Spread categories/frameworks as mutable arrays\n categories: [...originalDataset.config.categories],\n frameworks: [...originalDataset.config.frameworks],\n },\n samples,\n };\n\n // Format output\n let output: string;\n if (outputFormat === 'json') {\n output = JSON.stringify({ results, stats }, null, 2);\n } else {\n output = formatBenchmarkReport(results, dataset, outputFormat === 'detailed');\n\n // Add dataset stats\n output += '\\n## Dataset Statistics\\n\\n';\n output += `- **Total Samples:** ${samples.length}\\n`;\n output += `- **Verified Samples:** ${stats.statusDistribution.verified || 0}\\n`;\n output += `- **Drift Samples:** ${stats.statusDistribution.drift || 0}\\n`;\n output += `- **Undocumented Samples:** ${stats.statusDistribution.undocumented || 0}\\n`;\n output += `- **Unimplemented Samples:** ${stats.statusDistribution.unimplemented || 0}\\n`;\n }\n\n // Save to project's vasperaPM folder\n const defaults = getToolDefaults('run_benchmark');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'run_benchmark',\n category: defaults.category,\n filename: defaults.filename,\n content: output,\n format: outputFormat === 'json' ? 'json' : 'md',\n inputs: categories || frameworks || difficulties ? ['filtered'] : ['all'],\n tokensUsed: totalTokens,\n });\n\n if (outputFormat === 'json') {\n return jsonResult({ results, stats }, totalTokens);\n }\n\n return markdownResult(output + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Benchmark failed: ${message}`);\n }\n },\n\n requiredScope: 'tools:run_benchmark',\n};\n","/**\n * analyze_git_freshness Tool\n *\n * MCP tool that exposes the Git History Analysis module.\n * Analyzes documentation freshness, code-doc desync,\n * and predicts drift risk based on git history patterns.\n *\n * This tool wires the git-analysis module to the MCP server,\n * enabling users to detect stale documentation through Claude.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, jsonResult, errorResult } from './types.js';\nimport {\n runFullGitAnalysis,\n type GitAnalysisResult,\n} from '../git-analysis/index.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { DiscoveryAgent } from '../agents/index.js';\nimport { existsSync } from 'fs';\nimport { resolve } from 'path';\n\n/**\n * Format git analysis result as a human-readable markdown report\n */\nfunction formatGitAnalysisReport(\n result: GitAnalysisResult,\n includeDetails: boolean\n): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# Git Freshness Analysis Report');\n lines.push('');\n lines.push(`**Repository:** ${result.repoPath}`);\n lines.push(`**Analyzed:** ${new Date(result.analyzedAt).toISOString()}`);\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Documentation Files Analyzed | ${result.summary.totalDocsAnalyzed} |`);\n lines.push(`| Code Files Analyzed | ${result.summary.totalCodeFilesAnalyzed} |`);\n lines.push(`| Stale Documents | ${result.summary.staleDocCount} |`);\n lines.push(`| Desync Pairs | ${result.summary.desyncPairCount} |`);\n lines.push(`| High Risk Files | ${result.summary.highRiskFileCount} |`);\n lines.push('');\n\n // Status indicator\n const totalIssues = result.summary.staleDocCount + result.summary.desyncPairCount + result.summary.highRiskFileCount;\n if (totalIssues === 0) {\n lines.push('**Status:** ✅ All documentation is fresh and in sync');\n } else if (result.summary.staleDocCount > 0 && result.desync.overallDesyncRisk === 'high') {\n lines.push('**Status:** 🚨 Critical - Documentation significantly out of sync');\n } else if (result.summary.staleDocCount > 0) {\n lines.push(`**Status:** ⚠️ ${result.summary.staleDocCount} stale document(s) need attention`);\n } else {\n lines.push('**Status:** ℹ️ Minor sync issues detected');\n }\n lines.push('');\n\n // Freshness Analysis\n lines.push('## Documentation Freshness');\n lines.push('');\n lines.push(`**Average Freshness Score:** ${result.freshness.averageFreshness.toFixed(0)}/100`);\n lines.push('');\n\n if (result.freshness.staleDocuments.length > 0) {\n lines.push('### Stale Documents');\n lines.push('');\n lines.push('| Document | Days Since Update | Staleness | Related Code |');\n lines.push('|----------|-------------------|-----------|--------------|');\n for (const doc of result.freshness.staleDocuments) {\n const related = doc.relatedCodeFiles.slice(0, 2).join(', ') || '-';\n const stalenessEmoji = doc.staleness === 'critical' ? '🔴' : doc.staleness === 'high' ? '🟠' : '🟡';\n lines.push(`| ${doc.file} | ${doc.daysSinceUpdate} | ${stalenessEmoji} ${doc.staleness} | ${related} |`);\n }\n lines.push('');\n } else {\n lines.push('> ✅ No stale documents found');\n lines.push('');\n }\n\n // Desync Analysis\n lines.push('## Code-Documentation Desync');\n lines.push('');\n lines.push(`**Overall Desync Risk:** ${getRiskEmoji(result.desync.overallDesyncRisk)} ${result.desync.overallDesyncRisk}`);\n lines.push('');\n\n if (result.desync.desyncPairs.length > 0) {\n lines.push('### Desync Pairs');\n lines.push('');\n lines.push('| Code File | Doc File | Days Apart | Risk | Commits Since |');\n lines.push('|-----------|----------|------------|------|---------------|');\n for (const pair of result.desync.desyncPairs.slice(0, 15)) {\n const riskEmoji = getRiskEmoji(pair.desyncRisk);\n lines.push(`| ${truncatePath(pair.codePath)} | ${truncatePath(pair.docPath)} | ${pair.daysBetween} | ${riskEmoji} ${pair.desyncRisk} | ${pair.commitsSinceDocUpdate} |`);\n }\n if (result.desync.desyncPairs.length > 15) {\n lines.push(`| ... | ... | ... | ... | ... |`);\n lines.push(`| *${result.desync.desyncPairs.length - 15} more pairs* | | | | |`);\n }\n lines.push('');\n }\n\n if (result.desync.undocumentedChanges.length > 0) {\n lines.push('### Undocumented Changes');\n lines.push('');\n lines.push('Recent code changes that may need documentation updates:');\n lines.push('');\n for (const change of result.desync.undocumentedChanges.slice(0, 10)) {\n const severityEmoji = change.severity === 'high' ? '🔴' : change.severity === 'medium' ? '🟠' : '🟡';\n lines.push(`- ${severityEmoji} **${change.file}** - ${change.commit.message.split('\\n')[0]}`);\n if (change.relatedDocs.length > 0) {\n lines.push(` - Related docs: ${change.relatedDocs.slice(0, 2).join(', ')}`);\n }\n lines.push(` - Reason: ${change.reason}`);\n }\n if (result.desync.undocumentedChanges.length > 10) {\n lines.push(`- ... and ${result.desync.undocumentedChanges.length - 10} more undocumented changes`);\n }\n lines.push('');\n }\n\n // Drift Risk Analysis\n lines.push('## Drift Risk Prediction');\n lines.push('');\n lines.push(`**Overall Risk Score:** ${result.driftRisk.overallRiskScore}/100`);\n lines.push('');\n\n const highRiskFiles = result.driftRisk.fileScores.filter(\n (s) => s.riskLevel === 'critical' || s.riskLevel === 'high'\n );\n if (highRiskFiles.length > 0) {\n lines.push('### High Risk Files');\n lines.push('');\n lines.push('These files have high probability of drift:');\n lines.push('');\n lines.push('| File | Risk Score | Risk Level | Recommendation |');\n lines.push('|------|------------|------------|----------------|');\n for (const file of highRiskFiles.slice(0, 10)) {\n const levelEmoji = file.riskLevel === 'critical' ? '🔴' : '🟠';\n lines.push(`| ${truncatePath(file.file)} | ${file.riskScore}/100 | ${levelEmoji} ${file.riskLevel} | ${truncate(file.recommendation, 40)} |`);\n }\n lines.push('');\n }\n\n if (result.driftRisk.highRiskAreas.length > 0) {\n lines.push('### High Risk Areas');\n lines.push('');\n for (const area of result.driftRisk.highRiskAreas.slice(0, 5)) {\n lines.push(`**${area.riskLevel.toUpperCase()} Risk Area** (Score: ${area.averageRiskScore}/100)`);\n lines.push(`- Files: ${area.files.slice(0, 3).join(', ')}${area.files.length > 3 ? ` and ${area.files.length - 3} more` : ''}`);\n lines.push(`- Patterns: ${area.patterns.join(', ')}`);\n lines.push(`- Recommendation: ${area.recommendation}`);\n lines.push('');\n }\n }\n\n // Detailed file scores (if requested)\n if (includeDetails && result.freshness.freshnessScores.size > 0) {\n lines.push('## Detailed Freshness Scores');\n lines.push('');\n lines.push('| Document | Freshness | Days Old | Last Author | Commits |');\n lines.push('|----------|-----------|----------|-------------|---------|');\n for (const [file, freshness] of result.freshness.freshnessScores) {\n lines.push(`| ${truncatePath(file)} | ${freshness.freshnessScore}/100 | ${freshness.daysSinceUpdate} | ${freshness.lastAuthor} | ${freshness.totalCommits} |`);\n }\n lines.push('');\n }\n\n // Recommendations\n lines.push('## Recommendations');\n lines.push('');\n\n if (result.freshness.staleDocuments.length > 0) {\n const criticalStale = result.freshness.staleDocuments.filter((d) => d.staleness === 'critical');\n if (criticalStale.length > 0) {\n lines.push('### 🚨 Immediate Action Required');\n lines.push('');\n lines.push('These documents are critically stale and should be reviewed immediately:');\n lines.push('');\n for (const doc of criticalStale) {\n lines.push(`1. **${doc.file}** - Last updated ${doc.daysSinceUpdate} days ago by ${doc.lastAuthor}`);\n }\n lines.push('');\n }\n }\n\n if (result.desync.overallDesyncRisk === 'high') {\n lines.push('### ⚠️ Sync Review Needed');\n lines.push('');\n lines.push('Code has significantly diverged from documentation. Consider:');\n lines.push('- Running `verify_docs_code` for detailed drift analysis');\n lines.push('- Scheduling a documentation review sprint');\n lines.push('- Setting up automated doc-code sync checks in CI');\n lines.push('');\n }\n\n if (totalIssues === 0) {\n lines.push('> 🎉 Documentation is well-maintained! Keep up the good work.');\n lines.push('');\n lines.push('**Suggestions for maintaining freshness:**');\n lines.push('- Continue updating docs alongside code changes');\n lines.push('- Consider setting up automated freshness monitoring');\n lines.push('- Run this analysis periodically (weekly recommended)');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Get emoji for risk level\n */\nfunction getRiskEmoji(risk: 'critical' | 'high' | 'medium' | 'low' | string): string {\n switch (risk) {\n case 'critical':\n return '🔴';\n case 'high':\n return '🟠';\n case 'medium':\n return '🟡';\n case 'low':\n return '🟢';\n default:\n return '⚪';\n }\n}\n\n/**\n * Truncate a file path for display\n */\nfunction truncatePath(path: string, maxLength: number = 40): string {\n if (path.length <= maxLength) return path;\n const parts = path.split('/');\n if (parts.length <= 2) return path.slice(-maxLength);\n return '...' + path.slice(-(maxLength - 3));\n}\n\n/**\n * Truncate text for display\n */\nfunction truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength - 3) + '...';\n}\n\n/**\n * Discover doc and code files in a repo using DiscoveryAgent\n */\nasync function discoverFiles(repoPath: string): Promise<{\n docPaths: string[];\n codePaths: string[];\n}> {\n const discoveryAgent = new DiscoveryAgent();\n\n // Initialize with minimal context\n await discoveryAgent.initialize({\n projectPath: repoPath,\n outputPath: '',\n config: {\n maxTokensPerCall: 50000,\n maxRetries: 3,\n debateEnabled: false,\n confidenceThreshold: 70,\n model: 'balanced',\n },\n memory: {\n previousFindings: new Map(),\n patterns: new Map(),\n frameworkRules: new Map(),\n },\n });\n\n try {\n // Use DiscoveryAgent to find docs and code\n const docs = await discoveryAgent.discoverDocs(repoPath);\n const code = await discoveryAgent.discoverCode(repoPath);\n\n return {\n docPaths: docs.map((d) => d.path).slice(0, 30),\n codePaths: code.map((c) => c.path).slice(0, 50),\n };\n } finally {\n await discoveryAgent.shutdown();\n }\n}\n\n/**\n * analyze_git_freshness MCP Tool Definition\n */\nexport const analyzeGitFreshnessTool: ToolDefinition = {\n tool: {\n name: 'analyze_git_freshness',\n description: `Analyze documentation freshness and code-doc synchronization using git history.\n\nThis tool examines git commit history to:\n1. **Detect stale documentation** - Identify docs that haven't been updated in a long time\n2. **Find code-doc desync** - Detect when code has changed but related docs haven't\n3. **Predict drift risk** - Score files by likelihood of future drift based on patterns\n4. **Surface undocumented changes** - Find recent code changes that may need documentation\n\nMetrics produced:\n- **Freshness Score**: 0-100 score for each document (higher = fresher)\n- **Desync Risk**: Risk level for code-doc pairs (critical/high/medium/low)\n- **Drift Risk Score**: 0-100 prediction of drift likelihood\n\nBest for: Proactive documentation maintenance before drift occurs.`,\n inputSchema: {\n type: 'object',\n properties: {\n repoPath: {\n type: 'string',\n description: 'Path to the git repository to analyze',\n },\n docPaths: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific documentation files to analyze (auto-discovered if not provided)',\n },\n codePaths: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific code files to analyze (auto-discovered if not provided)',\n },\n staleThresholdDays: {\n type: 'number',\n default: 90,\n description: 'Days after which documentation is considered stale (default: 90)',\n },\n includeDetails: {\n type: 'boolean',\n default: false,\n description: 'Include detailed per-file freshness scores in output',\n },\n outputFormat: {\n type: 'string',\n enum: ['markdown', 'json'],\n default: 'markdown',\n description: 'Output format for the analysis report',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to repoPath)',\n },\n },\n required: ['repoPath'],\n },\n } as Tool,\n\n handler: async (args, _validation) => {\n const repoPath = args.repoPath as string;\n let docPaths = args.docPaths as string[] | undefined;\n let codePaths = args.codePaths as string[] | undefined;\n const staleThresholdDays = (args.staleThresholdDays as number) || 90;\n const includeDetails = args.includeDetails === true;\n const outputFormat = (args.outputFormat as string) || 'markdown';\n const projectRoot = (args.projectRoot as string) || repoPath;\n\n // Validate repo path exists\n const resolvedPath = resolve(repoPath);\n if (!existsSync(resolvedPath)) {\n return errorResult(`Repository path does not exist: ${resolvedPath}`);\n }\n\n try {\n // Auto-discover files if not provided\n if (!docPaths?.length || !codePaths?.length) {\n const discovered = await discoverFiles(resolvedPath);\n docPaths = docPaths?.length ? docPaths : discovered.docPaths;\n codePaths = codePaths?.length ? codePaths : discovered.codePaths;\n }\n\n // Check we have files to analyze\n if (docPaths.length === 0) {\n return errorResult('No documentation files found in repository. Provide docPaths or ensure docs exist.');\n }\n\n // Run full git analysis\n const result = await runFullGitAnalysis(\n resolvedPath,\n docPaths,\n codePaths,\n { staleThresholdDays }\n );\n\n // Format output\n let output: string;\n if (outputFormat === 'json') {\n // Convert Map to object for JSON serialization\n const serializableResult = {\n ...result,\n freshness: {\n ...result.freshness,\n freshnessScores: Object.fromEntries(result.freshness.freshnessScores),\n },\n };\n output = JSON.stringify(serializableResult, null, 2);\n } else {\n output = formatGitAnalysisReport(result, includeDetails);\n }\n\n // Save to project's vasperaPM folder\n const defaults = getToolDefaults('analyze_git_freshness');\n const saved = saveToolOutput({\n projectRoot: resolve(projectRoot),\n toolName: 'analyze_git_freshness',\n category: defaults.category,\n filename: defaults.filename,\n content: output,\n format: outputFormat === 'json' ? 'json' : 'md',\n inputs: [resolvedPath],\n tokensUsed: 0, // Git analysis doesn't use LLM tokens\n });\n\n if (outputFormat === 'json') {\n return jsonResult(result, 0);\n }\n\n return markdownResult(output + formatSavedPath(saved), 0);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Git analysis failed: ${message}`);\n }\n },\n\n requiredScope: 'tools:analyze_git_freshness',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, resolve, extname } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface DiscoveredDoc {\n path: string;\n relativePath: string;\n type: 'validation' | 'prd' | 'handoff' | 'spec' | 'architecture' | 'test' | 'other';\n content: string;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Discover VasperaPM output documents in a project\n */\nfunction discoverVasperaDocs(projectRoot: string): DiscoveredDoc[] {\n const docs: DiscoveredDoc[] = [];\n const resolvedPath = resolve(projectRoot);\n\n // Check for vasperaPM output folder\n const vasperaPath = join(resolvedPath, 'docs', 'vasperaPM');\n const docsPath = join(resolvedPath, 'docs');\n\n const searchPaths = [vasperaPath, docsPath];\n\n for (const searchPath of searchPaths) {\n if (!existsSync(searchPath)) continue;\n\n try {\n scanDirectory(searchPath, resolvedPath, docs);\n } catch {\n // Ignore errors\n }\n }\n\n return docs;\n}\n\nfunction scanDirectory(dir: string, projectRoot: string, docs: DiscoveredDoc[], depth = 0): void {\n if (depth > 4) return;\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = fullPath.replace(projectRoot + '/', '');\n\n if (entry.isDirectory()) {\n scanDirectory(fullPath, projectRoot, docs, depth + 1);\n continue;\n }\n\n if (!entry.isFile()) continue;\n\n const ext = extname(entry.name).toLowerCase();\n if (ext !== '.md' && ext !== '.json') continue;\n\n // Determine document type from filename/path\n const nameLower = entry.name.toLowerCase();\n const pathLower = relativePath.toLowerCase();\n let docType: DiscoveredDoc['type'] = 'other';\n\n if (nameLower.includes('validation') || nameLower.includes('validate')) {\n docType = 'validation';\n } else if (nameLower.includes('prd') || nameLower.includes('requirements')) {\n docType = 'prd';\n } else if (nameLower.includes('handoff') || nameLower.includes('handover')) {\n docType = 'handoff';\n } else if (nameLower.includes('spec') || nameLower.includes('specification')) {\n docType = 'spec';\n } else if (nameLower.includes('architecture') || nameLower.includes('arch')) {\n docType = 'architecture';\n } else if (nameLower.includes('test')) {\n docType = 'test';\n } else if (pathLower.includes('/code-analysis/')) {\n docType = 'validation';\n } else if (pathLower.includes('/handoff/')) {\n docType = 'handoff';\n } else if (pathLower.includes('/architecture/')) {\n docType = 'architecture';\n }\n\n try {\n const stat = statSync(fullPath);\n if (stat.size > 256 * 1024) continue; // Skip files > 256KB\n\n const content = readFileSync(fullPath, 'utf-8');\n docs.push({\n path: fullPath,\n relativePath,\n type: docType,\n content,\n });\n } catch {\n // Skip files that can't be read\n }\n }\n } catch {\n // Skip directories that can't be read\n }\n}\n\n/**\n * Format documents for the AI prompt\n */\nfunction formatDocsForPrompt(docs: DiscoveredDoc[], maxChars = 40000): string {\n const parts: string[] = [];\n let totalChars = 0;\n\n // Prioritize: validation > prd > handoff > spec > others\n const priority: Record<DiscoveredDoc['type'], number> = {\n validation: 1,\n prd: 2,\n handoff: 3,\n spec: 4,\n architecture: 5,\n test: 6,\n other: 7,\n };\n\n const sorted = [...docs].sort((a, b) => priority[a.type] - priority[b.type]);\n\n for (const doc of sorted) {\n const header = `\\n\\n## ${doc.type.toUpperCase()}: ${doc.relativePath}\\n`;\n const content = doc.content;\n\n if (totalChars + header.length + content.length > maxChars) {\n // Truncate this document\n const remaining = maxChars - totalChars - header.length - 100;\n if (remaining > 500) {\n parts.push(header + content.substring(0, remaining) + '\\n... [truncated]');\n }\n break;\n }\n\n parts.push(header + content);\n totalChars += header.length + content.length;\n }\n\n return parts.join('');\n}\n\n// ============================================================================\n// Main Tool Definition\n// ============================================================================\n\n/**\n * export_requirements tool - Consolidate requirements from VasperaPM outputs\n */\nexport const exportRequirementsTool: ToolDefinition = {\n tool: {\n name: 'export_requirements',\n description: `Consolidate requirements from VasperaPM outputs into a single source of truth.\n\nScans existing documentation (validation reports, PRDs, handoffs, specs) and produces:\n- Unified requirements list with IDs\n- Implementation status for each requirement\n- Evidence locations (file:line references)\n- ADO/JIRA-ready format for import\n\nBest for: Creating a single requirements document before sprint planning or handoff.`,\n inputSchema: {\n type: 'object',\n properties: {\n repoPath: {\n type: 'string',\n description: 'Path to project root (scans docs/vasperaPM for outputs)',\n },\n additionalDocs: {\n type: 'array',\n items: { type: 'string' },\n description: 'Additional document content to include in consolidation',\n },\n outputFormat: {\n type: 'string',\n enum: ['markdown', 'csv', 'json'],\n default: 'markdown',\n description: 'Output format for the requirements',\n },\n includeStatus: {\n type: 'boolean',\n default: true,\n description: 'Include implementation status from validation reports',\n },\n groupBy: {\n type: 'string',\n enum: ['category', 'status', 'priority', 'source'],\n default: 'category',\n description: 'How to group requirements in output',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to repoPath)',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const repoPath = (args.repoPath as string) || process.cwd();\n const additionalDocs = args.additionalDocs as string[] | undefined;\n const outputFormat = (args.outputFormat as string) || 'markdown';\n const includeStatus = args.includeStatus !== false;\n const groupBy = (args.groupBy as string) || 'category';\n const projectRoot = (args.projectRoot as string) || repoPath;\n\n // Discover existing VasperaPM documents\n const docs = discoverVasperaDocs(repoPath);\n\n if (docs.length === 0 && (!additionalDocs || additionalDocs.length === 0)) {\n return errorResult(\n `No VasperaPM documents found in ${repoPath}/docs/vasperaPM. ` +\n 'Run other VasperaPM tools first (handoff_package, validate_implementation, etc.) or provide additionalDocs.'\n );\n }\n\n // Add any additional documents\n if (additionalDocs) {\n for (let i = 0; i < additionalDocs.length; i++) {\n const docContent = additionalDocs[i];\n if (docContent) {\n docs.push({\n path: `additional-${i + 1}`,\n relativePath: `additional-doc-${i + 1}.md`,\n type: 'other',\n content: docContent,\n });\n }\n }\n }\n\n const formattedDocs = formatDocsForPrompt(docs);\n\n const systemPrompt = `You are a requirements analyst consolidating project documentation into a unified requirements list.\n\nYour task is to extract ALL requirements from the provided VasperaPM outputs and consolidate them into a single source of truth.\n\nFor each requirement, extract:\n- **ID**: Generate a unique ID (REQ-001, REQ-002, etc.)\n- **Category**: functional, non-functional, security, performance, ux, accessibility, data\n- **Description**: Clear, actionable requirement statement\n- **Priority**: critical, high, medium, low (infer from context)\n- **Status**: ${includeStatus ? 'implemented, partial, not_implemented, unknown (from validation reports)' : 'not tracked'}\n- **Source**: Which document(s) mention this requirement\n- **Evidence**: File:line references where implemented (if available from validation)\n\nCONSOLIDATION RULES:\n1. Merge duplicate requirements from different sources\n2. Use the most specific/detailed version when merging\n3. Note when sources conflict about a requirement\n4. Preserve file:line references from validation reports\n5. Group by ${groupBy}\n\nOUTPUT FORMAT: ${outputFormat === 'csv' ? 'CSV table with headers' : outputFormat === 'json' ? 'JSON array of requirement objects' : 'Markdown with tables'}\n\nInclude these sections:\n1. **Summary** - Total requirements, coverage statistics\n2. **Requirements by ${groupBy.charAt(0).toUpperCase() + groupBy.slice(1)}** - The consolidated list\n3. **Implementation Gaps** - Requirements not yet implemented\n4. **Conflicts** - Where sources disagree\n5. **ADO/JIRA Import** - Ready-to-import format`;\n\n const userMessage = `Consolidate requirements from these VasperaPM outputs:\n\n${formattedDocs}\n\nExtract all requirements and produce a unified, de-duplicated list grouped by ${groupBy}.\n${includeStatus ? 'Include implementation status from any validation reports.' : ''}\nOutput in ${outputFormat} format.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000,\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output\n const defaults = getToolDefaults('export_requirements');\n const saved = saveToolOutput({\n projectRoot: resolve(projectRoot),\n toolName: 'export_requirements',\n category: defaults.category || 'requirements',\n filename: defaults.filename || 'consolidated_requirements',\n content: result.text,\n format: outputFormat === 'json' ? 'json' : 'md', // CSV content saved as markdown\n inputs: docs.map((d) => d.type),\n tokensUsed: totalTokens,\n });\n\n return markdownResult(result.text + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to export requirements: ${message}`);\n }\n },\n\n requiredScope: 'tools:export_requirements',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport { createJsonCompletion, AIError } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n// ============================================================================\n// Types - Enhanced for Engineering Quality\n// ============================================================================\n\ninterface DiscoveredDocument {\n content: string;\n filename: string;\n}\n\ninterface DiscoveredDocuments {\n prd: DiscoveredDocument | null;\n architecture: DiscoveredDocument | null;\n apiDocs: DiscoveredDocument | null;\n testSpecs: DiscoveredDocument | null;\n refactors: DiscoveredDocument | null;\n dependencyAudit: DiscoveredDocument | null;\n userFlows: DiscoveredDocument | null;\n codebaseOverview: DiscoveredDocument | null;\n}\n\ntype CategoryType = 'features' | 'api' | 'infrastructure' | 'testing' | 'tech-debt' | 'security' | 'frontend';\n\n/**\n * Technical context for engineering delivery\n */\ninterface TechnicalContext {\n files?: string[];\n apiEndpoints?: string[];\n databaseTables?: string[];\n sourceDocRef?: string;\n}\n\n/**\n * Error handling specification\n */\ninterface ErrorHandlingSpec {\n scenarios: string[];\n statusCodes?: number[];\n userMessages?: string[];\n}\n\n/**\n * Non-functional requirements\n */\ninterface NFRs {\n performance?: string[];\n security?: string[];\n scalability?: string[];\n}\n\n/**\n * Task with technical details\n */\ninterface EnhancedTask {\n id: string;\n title: string;\n estimate?: string;\n files?: string[];\n}\n\n/**\n * Issue with full engineering context\n */\ninterface EnhancedIssue {\n id: string;\n title: string;\n description: string;\n acceptanceCriteria: string[];\n priority: 'critical' | 'high' | 'medium' | 'low';\n estimate?: string;\n technicalContext?: TechnicalContext;\n dependsOn?: string[];\n blocks?: string[];\n errorHandling?: ErrorHandlingSpec;\n nfrs?: NFRs;\n tasks?: EnhancedTask[];\n}\n\n/**\n * Epic structure\n */\ninterface EnhancedEpic {\n id: string;\n title: string;\n description: string;\n category: CategoryType;\n issues: EnhancedIssue[];\n}\n\n/**\n * Output from a single category generation call\n */\ninterface CategoryOutput {\n epic: EnhancedEpic;\n issueCount: number;\n taskCount: number;\n totalPoints: number;\n}\n\n/**\n * Complete backlog output\n */\ninterface BacklogOutput {\n epics: EnhancedEpic[];\n summary: {\n totalEpics: number;\n totalIssues: number;\n totalTasks: number;\n byCategory: Record<string, number>;\n byPriority: Record<string, number>;\n totalStoryPoints: number;\n };\n dependencyGraph?: {\n nodes: string[];\n edges: Array<{ from: string; to: string }>;\n criticalPath?: string[];\n };\n sourceDocuments: string[];\n}\n\n/**\n * Progress callback for UI updates\n */\ntype ProgressCallback = (phase: string, step: number, total: number, message: string) => void;\n\n// ============================================================================\n// Auto-Discovery\n// ============================================================================\n\nfunction discoverDocuments(projectRoot: string): DiscoveredDocuments {\n const vasperaPMPath = path.join(projectRoot, 'docs', 'vasperaPM');\n\n const findLatestVersion = (dir: string, pattern: string): DiscoveredDocument | null => {\n const fullDir = path.join(vasperaPMPath, dir);\n if (!fs.existsSync(fullDir)) return null;\n\n try {\n const files = fs.readdirSync(fullDir)\n .filter(f => f.startsWith(pattern) && (f.endsWith('.md') || f.endsWith('.json')))\n .sort()\n .reverse();\n\n const firstFile = files[0];\n if (firstFile) {\n const filePath = path.join(fullDir, firstFile);\n return {\n content: fs.readFileSync(filePath, 'utf-8'),\n filename: firstFile,\n };\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n return null;\n };\n\n return {\n prd: findLatestVersion('prd', 'inferred_prd') || findLatestVersion('prd', 'prd'),\n architecture: findLatestVersion('architecture', 'architecture'),\n apiDocs: findLatestVersion('api', 'api_docs'),\n testSpecs: findLatestVersion('test-specs', 'test_plan'),\n refactors: findLatestVersion('code-analysis', 'refactor_suggestions'),\n dependencyAudit: findLatestVersion('code-analysis', 'dependency_audit'),\n userFlows: findLatestVersion('code-analysis', 'user_flows'),\n codebaseOverview: findLatestVersion('code-analysis', 'codebase_overview'),\n };\n}\n\n// ============================================================================\n// Category-Specific Generation (Sequential Calls)\n// ============================================================================\n\ninterface CategoryConfig {\n category: CategoryType;\n document: DiscoveredDocument;\n projectKey: string;\n epicNumber: number;\n engineeringDetail: string;\n generateTasks: boolean;\n estimateUnit: string;\n contextDocs?: DiscoveredDocument[]; // Additional context (e.g., codebase overview)\n}\n\n/**\n * Generate epic for a single category from its source document\n * This is the core function that makes ONE focused AI call per category\n */\nasync function generateCategoryEpic(config: CategoryConfig): Promise<CategoryOutput> {\n const {\n category,\n document,\n projectKey,\n epicNumber,\n engineeringDetail,\n generateTasks,\n estimateUnit,\n contextDocs = [],\n } = config;\n\n const categoryPrompts: Record<CategoryType, { title: string; focus: string }> = {\n features: {\n title: 'Product Features',\n focus: 'user-facing features, functional requirements, and user stories from the PRD',\n },\n api: {\n title: 'API Implementation',\n focus: 'API endpoints, request/response contracts, authentication, and rate limiting',\n },\n infrastructure: {\n title: 'Infrastructure & Database',\n focus: 'database schema, tables, migrations, caching, and infrastructure setup',\n },\n testing: {\n title: 'Testing & QA',\n focus: 'test coverage, unit tests, integration tests, E2E tests, and QA processes',\n },\n 'tech-debt': {\n title: 'Technical Debt & Refactoring',\n focus: 'code refactoring, performance improvements, and technical debt reduction',\n },\n security: {\n title: 'Security & Compliance',\n focus: 'security vulnerabilities, dependency updates, compliance requirements',\n },\n frontend: {\n title: 'Frontend & UX',\n focus: 'UI components, user flows, accessibility, and frontend architecture',\n },\n };\n\n const prompt = categoryPrompts[category];\n const epicId = `${projectKey}-E${String(epicNumber).padStart(3, '0')}`;\n const issueStartNum = (epicNumber - 1) * 10 + 1;\n\n const detailLevel = {\n basic: 'Include 3-5 acceptance criteria per issue. Skip technical context and NFRs.',\n standard: 'Include technical context (files, endpoints, tables), 3-5 acceptance criteria, and basic error handling.',\n comprehensive: 'Include full technical context, detailed error handling with status codes, NFRs (performance, security, scalability), and 3-5 specific tasks per issue.',\n };\n\n const systemPrompt = `You are an expert at generating engineering-quality backlog items for software development teams.\n\nTASK: Generate a SINGLE epic with issues for the \"${category}\" category.\nFOCUS: ${prompt.focus}\nEPIC ID: ${epicId}\nEPIC TITLE: ${prompt.title}\n\nENGINEERING DETAIL LEVEL: ${engineeringDetail.toUpperCase()}\n${detailLevel[engineeringDetail as keyof typeof detailLevel]}\n\nOUTPUT FORMAT - Return ONLY this JSON structure:\n{\n \"epic\": {\n \"id\": \"${epicId}\",\n \"title\": \"${prompt.title}\",\n \"description\": \"Description based on the source document\",\n \"category\": \"${category}\",\n \"issues\": [\n {\n \"id\": \"${projectKey}-${String(issueStartNum).padStart(3, '0')}\",\n \"title\": \"Actionable title starting with verb\",\n \"description\": \"Detailed implementation description\",\n \"acceptanceCriteria\": [\"Given/When/Then or clear checkpoints\"],\n \"priority\": \"critical|high|medium|low\",\n \"estimate\": \"${estimateUnit === 'story_points' ? '5' : '4h'}\",\n ${engineeringDetail !== 'basic' ? `\"technicalContext\": {\n \"files\": [\"src/path/to/file.ts\"],\n \"apiEndpoints\": [\"POST /api/endpoint\"],\n \"databaseTables\": [\"table_name\"],\n \"sourceDocRef\": \"filename.md#section\"\n },\n \"errorHandling\": {\n \"scenarios\": [\"Error case description\"],\n \"statusCodes\": [400, 401, 500]\n },\n \"nfrs\": {\n \"performance\": [\"Response < 200ms\"],\n \"security\": [\"Input validation required\"]\n },` : ''}\n ${generateTasks ? `\"tasks\": [\n {\n \"id\": \"${projectKey}-${String(issueStartNum).padStart(3, '0')}-T1\",\n \"title\": \"Specific task\",\n \"estimate\": \"${estimateUnit === 'story_points' ? '2' : '2h'}\",\n \"files\": [\"src/file.ts\"]\n }\n ]` : ''}\n }\n ]\n },\n \"issueCount\": number,\n \"taskCount\": number,\n \"totalPoints\": number\n}\n\nRULES:\n1. Generate 3-8 issues based on the document content\n2. Every issue MUST have a unique ID following the pattern ${projectKey}-XXX\n3. Extract ACTUAL file paths, endpoints, and tables from the document - don't make them up\n4. Prioritize: critical (blocking/security) > high (core functionality) > medium > low\n5. Use Fibonacci for story points: 1, 2, 3, 5, 8, 13\n6. Issues should be actionable and specific, not vague\n7. Include sourceDocRef pointing to the source document filename`;\n\n let userMessage = `Generate the \"${category}\" epic from this source document:\\n\\n`;\n userMessage += `=== SOURCE: ${document.filename} ===\\n`;\n userMessage += document.content.substring(0, 8000); // Limit per-document content\n\n // Add context documents if available\n for (const ctx of contextDocs) {\n userMessage += `\\n\\n=== CONTEXT: ${ctx.filename} ===\\n`;\n userMessage += ctx.content.substring(0, 2000);\n }\n\n userMessage += '\\n\\nGenerate the epic JSON now. Extract REAL file paths and technical details from the document.';\n\n const result = await createJsonCompletion<CategoryOutput>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 6000, // Smaller per-category call\n expectedKeys: ['epic', 'issueCount', 'taskCount', 'totalPoints'],\n });\n\n return result.data;\n}\n\n// ============================================================================\n// Merge & Cross-Reference\n// ============================================================================\n\ninterface MergeConfig {\n categoryOutputs: CategoryOutput[];\n sourceDocuments: string[];\n projectKey: string;\n}\n\n/**\n * Merge category outputs and calculate cross-references\n */\nfunction mergeAndCrossReference(config: MergeConfig): BacklogOutput {\n const { categoryOutputs, sourceDocuments, projectKey } = config;\n\n const epics: EnhancedEpic[] = [];\n const allIssueIds: string[] = [];\n const edges: Array<{ from: string; to: string }> = [];\n let totalIssues = 0;\n let totalTasks = 0;\n let totalPoints = 0;\n const byCategory: Record<string, number> = {};\n const byPriority: Record<string, number> = { critical: 0, high: 0, medium: 0, low: 0 };\n\n // Collect all epics and issues\n for (const output of categoryOutputs) {\n epics.push(output.epic);\n totalIssues += output.issueCount;\n totalTasks += output.taskCount;\n totalPoints += output.totalPoints;\n byCategory[output.epic.category] = output.issueCount;\n\n for (const issue of output.epic.issues) {\n allIssueIds.push(issue.id);\n byPriority[issue.priority] = (byPriority[issue.priority] || 0) + 1;\n\n // Collect declared dependencies\n if (issue.dependsOn) {\n for (const dep of issue.dependsOn) {\n edges.push({ from: issue.id, to: dep });\n }\n }\n }\n }\n\n // Auto-detect cross-category dependencies based on patterns\n const authIssues = allIssueIds.filter(id =>\n epics.some(e => e.issues.some(i =>\n i.id === id && (i.title.toLowerCase().includes('auth') || i.title.toLowerCase().includes('login'))\n ))\n );\n\n const apiIssues = epics\n .filter(e => e.category === 'api')\n .flatMap(e => e.issues.map(i => i.id));\n\n const infraIssues = epics\n .filter(e => e.category === 'infrastructure')\n .flatMap(e => e.issues.map(i => i.id));\n\n // API issues depend on auth\n for (const apiId of apiIssues) {\n for (const authId of authIssues) {\n if (apiId !== authId && !edges.some(e => e.from === apiId && e.to === authId)) {\n edges.push({ from: apiId, to: authId });\n }\n }\n }\n\n // Features depend on infrastructure (first infra issue)\n const firstInfraIssue = infraIssues[0];\n if (firstInfraIssue) {\n const featureIssues = epics\n .filter(e => e.category === 'features')\n .flatMap(e => e.issues.map(i => i.id));\n\n for (const featureId of featureIssues.slice(0, 3)) { // Link first 3 features\n if (!edges.some(e => e.from === featureId && e.to === firstInfraIssue)) {\n edges.push({ from: featureId, to: firstInfraIssue });\n }\n }\n }\n\n // Calculate critical path (simplified: longest chain)\n const criticalPath = calculateCriticalPath(allIssueIds, edges);\n\n return {\n epics,\n summary: {\n totalEpics: epics.length,\n totalIssues,\n totalTasks,\n byCategory,\n byPriority,\n totalStoryPoints: totalPoints,\n },\n dependencyGraph: {\n nodes: allIssueIds,\n edges,\n criticalPath,\n },\n sourceDocuments,\n };\n}\n\n/**\n * Simple critical path calculation\n */\nfunction calculateCriticalPath(nodes: string[], edges: Array<{ from: string; to: string }>): string[] {\n // Build adjacency list (reversed for traversal)\n const dependents: Record<string, string[]> = {};\n const dependencies: Record<string, string[]> = {};\n\n for (const node of nodes) {\n dependents[node] = [];\n dependencies[node] = [];\n }\n\n for (const edge of edges) {\n if (dependents[edge.to]) {\n dependents[edge.to].push(edge.from);\n }\n if (dependencies[edge.from]) {\n dependencies[edge.from].push(edge.to);\n }\n }\n\n // Find nodes with no dependencies (start points)\n const startNodes = nodes.filter(n => (dependencies[n]?.length ?? 0) === 0);\n\n // Find longest path from any start node\n let longestPath: string[] = [];\n\n function dfs(node: string, path: string[], visited: Set<string>): void {\n if (visited.has(node)) return;\n visited.add(node);\n path.push(node);\n\n if (path.length > longestPath.length) {\n longestPath = [...path];\n }\n\n const deps = dependents[node] ?? [];\n for (const dependent of deps) {\n dfs(dependent, path, visited);\n }\n\n path.pop();\n visited.delete(node);\n }\n\n for (const start of startNodes) {\n dfs(start, [], new Set());\n }\n\n return longestPath.reverse(); // Return in execution order\n}\n\n// ============================================================================\n// Output Formatting\n// ============================================================================\n\nfunction generateMarkdownOutput(output: BacklogOutput, platform: string, adoProcess?: string): string {\n const lines: string[] = [];\n\n lines.push('# Complete Project Backlog');\n lines.push('');\n lines.push(`**Platform:** ${platform.toUpperCase()}${adoProcess ? ` (${adoProcess})` : ''}`);\n lines.push(`**Generated:** ${new Date().toISOString()}`);\n lines.push(`**Architecture:** Sequential category generation with cross-referencing`);\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Count |');\n lines.push('|--------|-------|');\n lines.push(`| Epics | ${output.summary.totalEpics} |`);\n lines.push(`| Issues | ${output.summary.totalIssues} |`);\n lines.push(`| Tasks | ${output.summary.totalTasks} |`);\n lines.push(`| **Total Story Points** | **${output.summary.totalStoryPoints}** |`);\n lines.push('');\n\n // By Category\n lines.push('### By Category');\n lines.push('');\n for (const [category, count] of Object.entries(output.summary.byCategory)) {\n lines.push(`- ${getCategoryIcon(category)} **${category}**: ${count} issues`);\n }\n lines.push('');\n\n // By Priority\n lines.push('### By Priority');\n lines.push('');\n for (const [priority, count] of Object.entries(output.summary.byPriority)) {\n if (count > 0) {\n lines.push(`- ${getPriorityIcon(priority)} **${priority}**: ${count}`);\n }\n }\n lines.push('');\n\n // Source Documents\n if (output.sourceDocuments.length > 0) {\n lines.push('### Source Documents');\n lines.push('');\n for (const doc of output.sourceDocuments) {\n lines.push(`- \\`${doc}\\``);\n }\n lines.push('');\n }\n\n // Dependency Graph\n if (output.dependencyGraph && output.dependencyGraph.edges.length > 0) {\n lines.push('### Dependency Overview');\n lines.push('');\n lines.push(`- **Dependency links:** ${output.dependencyGraph.edges.length}`);\n if (output.dependencyGraph.criticalPath && output.dependencyGraph.criticalPath.length > 0) {\n lines.push(`- **Critical path:** ${output.dependencyGraph.criticalPath.join(' → ')}`);\n }\n lines.push('');\n }\n\n // Hierarchy Tree\n lines.push('## Backlog Hierarchy');\n lines.push('');\n lines.push('```');\n for (const epic of output.epics) {\n lines.push(`${getCategoryIcon(epic.category)} ${epic.id}: ${epic.title}`);\n for (let i = 0; i < epic.issues.length; i++) {\n const issue = epic.issues[i];\n const prefix = i === epic.issues.length - 1 ? '└── ' : '├── ';\n const deps = issue.dependsOn?.length ? ` [→ ${issue.dependsOn.join(', ')}]` : '';\n lines.push(` ${prefix}${getPriorityIcon(issue.priority)} ${issue.id}: ${issue.title}${deps}`);\n }\n lines.push('');\n }\n lines.push('```');\n lines.push('');\n\n // Detailed Items\n lines.push('## Detailed Items');\n lines.push('');\n\n for (const epic of output.epics) {\n lines.push(`### ${getCategoryIcon(epic.category)} ${epic.id}: ${epic.title}`);\n lines.push('');\n lines.push(`**Category:** ${epic.category}`);\n lines.push('');\n lines.push(epic.description);\n lines.push('');\n\n for (const issue of epic.issues) {\n lines.push(`#### ${getPriorityIcon(issue.priority)} ${issue.id}: ${issue.title}`);\n lines.push('');\n lines.push(`**Priority:** ${issue.priority} | **Estimate:** ${issue.estimate || 'TBD'}`);\n lines.push('');\n\n if (issue.dependsOn?.length) {\n lines.push(`**Depends on:** ${issue.dependsOn.join(', ')}`);\n lines.push('');\n }\n\n lines.push(issue.description);\n lines.push('');\n\n if (issue.technicalContext) {\n lines.push('**Technical Context:**');\n if (issue.technicalContext.files?.length) {\n lines.push(`- Files: ${issue.technicalContext.files.map(f => `\\`${f}\\``).join(', ')}`);\n }\n if (issue.technicalContext.apiEndpoints?.length) {\n lines.push(`- Endpoints: ${issue.technicalContext.apiEndpoints.join(', ')}`);\n }\n if (issue.technicalContext.databaseTables?.length) {\n lines.push(`- Tables: ${issue.technicalContext.databaseTables.join(', ')}`);\n }\n if (issue.technicalContext.sourceDocRef) {\n lines.push(`- Source: ${issue.technicalContext.sourceDocRef}`);\n }\n lines.push('');\n }\n\n if (issue.acceptanceCriteria?.length) {\n lines.push('**Acceptance Criteria:**');\n for (const ac of issue.acceptanceCriteria) {\n lines.push(`- [ ] ${ac}`);\n }\n lines.push('');\n }\n\n if (issue.errorHandling?.scenarios?.length) {\n lines.push('**Error Handling:**');\n for (const scenario of issue.errorHandling.scenarios) {\n lines.push(`- ${scenario}`);\n }\n lines.push('');\n }\n\n if (issue.nfrs) {\n const nfrItems: string[] = [];\n if (issue.nfrs.performance?.length) nfrItems.push(`Performance: ${issue.nfrs.performance.join('; ')}`);\n if (issue.nfrs.security?.length) nfrItems.push(`Security: ${issue.nfrs.security.join('; ')}`);\n if (issue.nfrs.scalability?.length) nfrItems.push(`Scalability: ${issue.nfrs.scalability.join('; ')}`);\n if (nfrItems.length) {\n lines.push('**NFRs:** ' + nfrItems.join(' | '));\n lines.push('');\n }\n }\n\n if (issue.tasks?.length) {\n lines.push('**Tasks:**');\n for (const task of issue.tasks) {\n let taskLine = `- [ ] ${task.id}: ${task.title}`;\n if (task.estimate) taskLine += ` (${task.estimate})`;\n if (task.files?.length) taskLine += ` → \\`${task.files[0]}\\``;\n lines.push(taskLine);\n }\n lines.push('');\n }\n }\n }\n\n // JSON Export\n lines.push('---');\n lines.push('');\n lines.push('<details>');\n lines.push('<summary>📦 Full JSON Export</summary>');\n lines.push('');\n lines.push('```json');\n lines.push(JSON.stringify(output, null, 2));\n lines.push('```');\n lines.push('</details>');\n\n return lines.join('\\n');\n}\n\nfunction getCategoryIcon(category: string): string {\n const icons: Record<string, string> = {\n features: '🎯',\n api: '🔌',\n infrastructure: '🏗️',\n testing: '🧪',\n 'tech-debt': '🔧',\n security: '🔒',\n frontend: '🎨',\n };\n return icons[category] || '📋';\n}\n\nfunction getPriorityIcon(priority: string): string {\n const icons: Record<string, string> = {\n critical: '🔴',\n high: '🟠',\n medium: '🟡',\n low: '🟢',\n };\n return icons[priority] || '⚪';\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const generateCompleteBacklogTool: ToolDefinition = {\n tool: {\n name: 'generate_complete_backlog',\n description: `Generate a comprehensive, engineering-quality project backlog using sequential category-based AI calls.\n\n**Architecture:** Makes focused AI calls per category (one document at a time) for reliability and accuracy, then merges results with cross-referencing.\n\n**Categories generated:**\n- 🎯 Features - From PRD/requirements\n- 🔌 API - From API documentation\n- 🏗️ Infrastructure - From architecture docs\n- 🧪 Testing - From test specifications\n- 🔧 Tech Debt - From refactor suggestions\n- 🔒 Security - From dependency audit\n- 🎨 Frontend - From user flows\n\n**Engineering enhancements:**\n- Technical context (files, endpoints, tables)\n- Cross-category dependency mapping\n- Error handling specifications\n- Non-functional requirements\n\nAuto-discovers documents from docs/vasperaPM/. Best for: Sprint planning with full engineering context.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n platform: {\n type: 'string',\n enum: ['ado', 'jira', 'linear', 'github'],\n default: 'ado',\n description: 'Target project management platform',\n },\n adoProcess: {\n type: 'string',\n enum: ['basic', 'agile', 'scrum', 'cmmi'],\n default: 'basic',\n description: 'ADO process template',\n },\n projectKey: {\n type: 'string',\n default: 'VPM',\n description: 'Project key prefix for IDs',\n },\n engineeringDetail: {\n type: 'string',\n enum: ['basic', 'standard', 'comprehensive'],\n default: 'standard',\n description: 'Level of engineering detail',\n },\n includeFeatures: { type: 'boolean', default: true },\n includeApi: { type: 'boolean', default: true },\n includeInfrastructure: { type: 'boolean', default: true },\n includeTesting: { type: 'boolean', default: true },\n includeTechDebt: { type: 'boolean', default: true },\n includeSecurity: { type: 'boolean', default: true },\n includeFrontend: { type: 'boolean', default: true },\n generateTasks: { type: 'boolean', default: true },\n estimateUnit: {\n type: 'string',\n enum: ['story_points', 'hours'],\n default: 'story_points',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const platform = (args.platform as string) || 'ado';\n const adoProcess = (args.adoProcess as string) || 'basic';\n const projectKey = (args.projectKey as string) || 'VPM';\n const engineeringDetail = (args.engineeringDetail as string) || 'standard';\n const generateTasks = args.generateTasks !== false;\n const estimateUnit = (args.estimateUnit as string) || 'story_points';\n\n const includes = {\n features: args.includeFeatures !== false,\n api: args.includeApi !== false,\n infrastructure: args.includeInfrastructure !== false,\n testing: args.includeTesting !== false,\n 'tech-debt': args.includeTechDebt !== false,\n security: args.includeSecurity !== false,\n frontend: args.includeFrontend !== false,\n };\n\n // Phase 1: Discover documents\n console.error('[VasperaPM] Phase 1: Discovering documents...');\n const docs = discoverDocuments(projectRoot);\n\n const docCount = Object.values(docs).filter(d => d !== null).length;\n if (docCount === 0) {\n return errorResult(\n `No VasperaPM documents found in ${path.join(projectRoot, 'docs', 'vasperaPM')}. ` +\n 'Run other VasperaPM tools first to generate documentation.'\n );\n }\n\n // Map categories to their source documents\n const categoryDocMap: Array<{ category: CategoryType; doc: DiscoveredDocument; include: boolean }> = [\n { category: 'features', doc: docs.prd!, include: includes.features && !!docs.prd },\n { category: 'api', doc: docs.apiDocs!, include: includes.api && !!docs.apiDocs },\n { category: 'infrastructure', doc: docs.architecture!, include: includes.infrastructure && !!docs.architecture },\n { category: 'testing', doc: docs.testSpecs!, include: includes.testing && !!docs.testSpecs },\n { category: 'tech-debt', doc: docs.refactors!, include: includes['tech-debt'] && !!docs.refactors },\n { category: 'security', doc: docs.dependencyAudit!, include: includes.security && !!docs.dependencyAudit },\n { category: 'frontend', doc: docs.userFlows!, include: includes.frontend && !!docs.userFlows },\n ];\n\n const categoriesToProcess = categoryDocMap.filter(c => c.include);\n\n if (categoriesToProcess.length === 0) {\n return errorResult('No documents found for the enabled categories.');\n }\n\n // Phase 2: Generate epics sequentially per category\n console.error(`[VasperaPM] Phase 2: Generating ${categoriesToProcess.length} category epics...`);\n\n const categoryOutputs: CategoryOutput[] = [];\n const sourceDocuments: string[] = [];\n let totalTokens = 0;\n const errors: string[] = [];\n\n for (let i = 0; i < categoriesToProcess.length; i++) {\n const { category, doc } = categoriesToProcess[i]!;\n console.error(`[VasperaPM] ${i + 1}/${categoriesToProcess.length}: Generating ${category} epic...`);\n\n try {\n const output = await generateCategoryEpic({\n category,\n document: doc,\n projectKey,\n epicNumber: i + 1,\n engineeringDetail,\n generateTasks,\n estimateUnit,\n contextDocs: docs.codebaseOverview ? [docs.codebaseOverview] : [],\n });\n\n categoryOutputs.push(output);\n sourceDocuments.push(doc.filename);\n console.error(`[VasperaPM] ✓ Generated ${output.issueCount} issues, ${output.taskCount} tasks`);\n } catch (error) {\n const message = error instanceof AIError\n ? `${error.code}: ${error.message}`\n : error instanceof Error\n ? error.message\n : 'Unknown error';\n\n console.error(`[VasperaPM] ✗ Failed: ${message}`);\n errors.push(`${category}: ${message}`);\n\n // Continue with other categories even if one fails\n }\n }\n\n if (categoryOutputs.length === 0) {\n return errorResult(\n `Failed to generate any category epics.\\n\\nErrors:\\n${errors.join('\\n')}`\n );\n }\n\n // Phase 3: Merge and cross-reference\n console.error('[VasperaPM] Phase 3: Merging and cross-referencing...');\n const output = mergeAndCrossReference({\n categoryOutputs,\n sourceDocuments,\n projectKey,\n });\n\n // Phase 4: Generate output\n console.error('[VasperaPM] Phase 4: Generating output...');\n const markdown = generateMarkdownOutput(output, platform, adoProcess);\n\n // Add generation summary\n const summaryHeader = `## Generation Summary\n\n- **Categories processed:** ${categoryOutputs.length}/${categoriesToProcess.length}\n- **Documents discovered:** ${docCount}\n${errors.length > 0 ? `- **Errors:** ${errors.length} (see below)` : ''}\n\n${errors.length > 0 ? `### Generation Errors\\n${errors.map(e => `- ${e}`).join('\\n')}\\n` : ''}\n---\n\n`;\n\n const finalOutput = summaryHeader + markdown;\n\n // Save output\n const defaults = getToolDefaults('generate_complete_backlog');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_complete_backlog',\n category: defaults.category,\n filename: 'complete_backlog',\n content: finalOutput,\n format: 'md',\n inputs: [platform, adoProcess, `${categoryOutputs.length} categories`, `detail:${engineeringDetail}`],\n tokensUsed: totalTokens,\n structuredData: output,\n });\n\n console.error(`[VasperaPM] ✓ Complete! Generated ${output.summary.totalIssues} issues across ${output.summary.totalEpics} epics`);\n\n return markdownResult(finalOutput + formatSavedPath(saved), totalTokens);\n },\n\n requiredScope: 'tools:generate_complete_backlog',\n};\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { markdownResult, errorResult } from './types.js';\nimport { createCompletion } from '../ai/client.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport { existsSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, resolve, relative } from 'path';\n\n// ============================================================================\n// Deployment Config Discovery\n// ============================================================================\n\ninterface DeploymentFile {\n path: string;\n relativePath: string;\n type: 'docker' | 'compose' | 'ci' | 'k8s' | 'terraform' | 'env' | 'config' | 'script';\n content: string;\n}\n\n/**\n * Auto-discover deployment-related files in a repository\n */\nfunction discoverDeploymentFiles(repoPath: string): DeploymentFile[] {\n const files: DeploymentFile[] = [];\n const absoluteRoot = resolve(repoPath);\n\n // File patterns to look for\n const patterns = [\n // Docker\n { pattern: 'Dockerfile', type: 'docker' as const },\n { pattern: 'Dockerfile.*', type: 'docker' as const },\n { pattern: '*.dockerfile', type: 'docker' as const },\n { pattern: 'docker-compose.yml', type: 'compose' as const },\n { pattern: 'docker-compose.yaml', type: 'compose' as const },\n { pattern: 'docker-compose.*.yml', type: 'compose' as const },\n { pattern: 'compose.yml', type: 'compose' as const },\n // CI/CD\n { pattern: '.github/workflows/*.yml', type: 'ci' as const },\n { pattern: '.github/workflows/*.yaml', type: 'ci' as const },\n { pattern: '.gitlab-ci.yml', type: 'ci' as const },\n { pattern: 'azure-pipelines.yml', type: 'ci' as const },\n { pattern: 'azure-pipelines.yaml', type: 'ci' as const },\n { pattern: '.circleci/config.yml', type: 'ci' as const },\n { pattern: 'Jenkinsfile', type: 'ci' as const },\n { pattern: 'bitbucket-pipelines.yml', type: 'ci' as const },\n // Kubernetes\n { pattern: 'k8s/*.yml', type: 'k8s' as const },\n { pattern: 'k8s/*.yaml', type: 'k8s' as const },\n { pattern: 'kubernetes/*.yml', type: 'k8s' as const },\n { pattern: 'kubernetes/*.yaml', type: 'k8s' as const },\n { pattern: 'helm/**/*.yaml', type: 'k8s' as const },\n // Terraform/IaC\n { pattern: '*.tf', type: 'terraform' as const },\n { pattern: 'terraform/*.tf', type: 'terraform' as const },\n { pattern: 'infra/*.tf', type: 'terraform' as const },\n { pattern: 'pulumi/*.ts', type: 'terraform' as const },\n // Environment files\n { pattern: '.env.example', type: 'env' as const },\n { pattern: '.env.sample', type: 'env' as const },\n { pattern: '.env.template', type: 'env' as const },\n { pattern: 'env.example', type: 'env' as const },\n // Config files\n { pattern: 'vercel.json', type: 'config' as const },\n { pattern: 'netlify.toml', type: 'config' as const },\n { pattern: 'fly.toml', type: 'config' as const },\n { pattern: 'render.yaml', type: 'config' as const },\n { pattern: 'railway.json', type: 'config' as const },\n { pattern: 'app.yaml', type: 'config' as const },\n // Deployment scripts\n { pattern: 'scripts/deploy*.sh', type: 'script' as const },\n { pattern: 'scripts/deploy*.ts', type: 'script' as const },\n { pattern: 'deploy*.sh', type: 'script' as const },\n ];\n\n // Simple recursive file finder\n function findFiles(dir: string): void {\n if (!existsSync(dir)) return;\n\n try {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n\n // Skip node_modules, .git, and hidden directories (except .github, .circleci, etc.)\n if (entry === 'node_modules' || entry === '.git' || entry === 'dist' || entry === 'build') continue;\n\n try {\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n findFiles(fullPath);\n } else if (stat.isFile()) {\n const relativePath = relative(absoluteRoot, fullPath);\n\n // Check against each pattern\n for (const { pattern, type } of patterns) {\n if (matchPattern(relativePath, pattern)) {\n const content = readFileSync(fullPath, 'utf-8');\n // Limit content size\n files.push({\n path: fullPath,\n relativePath,\n type,\n content: content.length > 3000 ? content.substring(0, 3000) + '\\n... [truncated]' : content,\n });\n break; // Only match once per file\n }\n }\n }\n } catch {\n // Skip files we can't read\n }\n }\n } catch {\n // Skip directories we can't read\n }\n }\n\n // Simple glob pattern matching\n function matchPattern(filePath: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/\\./g, '\\\\.')\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*')\n .replace(/\\//g, '\\\\/');\n return new RegExp(`^${regexPattern}$`).test(filePath);\n }\n\n findFiles(absoluteRoot);\n return files;\n}\n\n/**\n * Detect the primary platform from discovered files\n */\nfunction detectPlatform(files: DeploymentFile[]): string[] {\n const platforms: string[] = [];\n\n for (const file of files) {\n if (file.relativePath.includes('.github/workflows')) platforms.push('github-actions');\n if (file.relativePath.includes('azure-pipelines')) platforms.push('azure-devops');\n if (file.relativePath.includes('.gitlab-ci')) platforms.push('gitlab-ci');\n if (file.relativePath.includes('vercel.json')) platforms.push('vercel');\n if (file.relativePath.includes('netlify.toml')) platforms.push('netlify');\n if (file.relativePath.includes('fly.toml')) platforms.push('fly-io');\n if (file.relativePath.includes('railway')) platforms.push('railway');\n if (file.relativePath.includes('render.yaml')) platforms.push('render');\n if (file.type === 'docker' || file.type === 'compose') platforms.push('docker');\n if (file.type === 'k8s') platforms.push('kubernetes');\n if (file.type === 'terraform') platforms.push('terraform');\n }\n\n return [...new Set(platforms)];\n}\n\n/**\n * Format discovered files for the AI prompt\n */\nfunction formatFilesForPrompt(files: DeploymentFile[]): string {\n if (files.length === 0) return '';\n\n const lines: string[] = ['## Discovered Deployment Files\\n'];\n\n // Group by type\n const byType = files.reduce(\n (acc, file) => {\n acc[file.type] = acc[file.type] || [];\n acc[file.type].push(file);\n return acc;\n },\n {} as Record<string, DeploymentFile[]>\n );\n\n for (const [type, typeFiles] of Object.entries(byType)) {\n lines.push(`### ${type.toUpperCase()} Files\\n`);\n for (const file of typeFiles) {\n lines.push(`#### ${file.relativePath}`);\n const ext = file.relativePath.split('.').pop() || '';\n const lang = { yml: 'yaml', yaml: 'yaml', json: 'json', tf: 'hcl', ts: 'typescript', sh: 'bash' }[ext] || '';\n lines.push('```' + lang);\n lines.push(file.content);\n lines.push('```\\n');\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * generate_deployment_runbook tool - Creates production deployment guide\n */\nexport const generateDeploymentRunbookTool: ToolDefinition = {\n tool: {\n name: 'generate_deployment_runbook',\n description: `Generate a comprehensive deployment runbook for production readiness.\n\nTakes a codebase or PRD and creates:\n- Environment configuration guide (dev/staging/prod)\n- CI/CD pipeline setup (GitHub Actions, Azure Pipelines, GitLab CI)\n- Container orchestration guide (Docker, Kubernetes)\n- Monitoring and alerting setup\n- Rollback procedures\n- Health check endpoints\n- Secret management\n\nSupports auto-discovery of existing deployment files (Dockerfile, CI configs, etc.).\n\nBest for: Production readiness and DevOps handoff.`,\n inputSchema: {\n type: 'object',\n properties: {\n requirements: {\n type: 'string',\n description: 'Product requirements, architecture doc, or deployment context',\n },\n repoPath: {\n type: 'string',\n description: 'Path to repository for auto-discovery of deployment files',\n },\n targetPlatform: {\n type: 'string',\n enum: ['aws', 'gcp', 'azure', 'vercel', 'netlify', 'fly-io', 'railway', 'render', 'self-hosted'],\n description: 'Target deployment platform (auto-detected if repoPath provided)',\n },\n ciPlatform: {\n type: 'string',\n enum: ['github-actions', 'azure-devops', 'gitlab-ci', 'circleci', 'jenkins'],\n default: 'github-actions',\n description: 'CI/CD platform to generate pipelines for',\n },\n includeMonitoring: {\n type: 'boolean',\n default: true,\n description: 'Include monitoring and alerting setup',\n },\n includeRollback: {\n type: 'boolean',\n default: true,\n description: 'Include rollback procedures',\n },\n environments: {\n type: 'array',\n items: { type: 'string' },\n default: ['development', 'staging', 'production'],\n description: 'Environments to generate configs for',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path for saving output (defaults to current directory)',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const requirements = (args.requirements as string) || '';\n const repoPath = args.repoPath as string | undefined;\n const targetPlatform = args.targetPlatform as string | undefined;\n const ciPlatform = (args.ciPlatform as string) || 'github-actions';\n const includeMonitoring = args.includeMonitoring !== false;\n const includeRollback = args.includeRollback !== false;\n const environments = (args.environments as string[]) || ['development', 'staging', 'production'];\n const projectRoot = (args.projectRoot as string) || repoPath || process.cwd();\n\n // Auto-discover deployment files if repoPath provided\n let deploymentContext = '';\n let discoveredFiles: DeploymentFile[] = [];\n let detectedPlatforms: string[] = [];\n\n if (repoPath) {\n discoveredFiles = discoverDeploymentFiles(repoPath);\n if (discoveredFiles.length > 0) {\n deploymentContext = formatFilesForPrompt(discoveredFiles);\n detectedPlatforms = detectPlatform(discoveredFiles);\n }\n }\n\n const platform = targetPlatform || detectedPlatforms[0] || 'self-hosted';\n\n const systemPrompt = `You are a senior DevOps engineer creating a comprehensive deployment runbook.\n\n${deploymentContext ? 'IMPORTANT: Deployment files have been auto-discovered from the codebase. Build upon these existing configurations.\\n' : ''}\n\nGenerate a production-ready deployment runbook with these sections:\n\n## 1. Prerequisites\n- Required tools and versions (Node.js, Docker, kubectl, terraform, etc.)\n- Access requirements (cloud accounts, service accounts, secrets)\n- Repository setup\n\n## 2. Environment Configuration\nFor each environment (${environments.join(', ')}):\n- Environment variables with descriptions\n- Secrets management (how to set up and rotate)\n- Resource sizing (CPU, memory, instances)\n- Database/cache configuration\n- Feature flags\n\n${includeMonitoring ? `## 3. Monitoring & Alerting\n- Health check endpoints to implement\n- Metrics to track (latency, error rate, throughput)\n- Log aggregation setup\n- Alerting rules (when to page, when to email)\n- Dashboard recommendations\n` : ''}\n\n## 4. CI/CD Pipeline (${ciPlatform})\n- Complete pipeline configuration (${ciPlatform === 'github-actions' ? 'YAML workflow' : ciPlatform === 'azure-devops' ? 'azure-pipelines.yml' : 'pipeline config'})\n- Build stage (lint, test, build)\n- Deploy stage (per environment)\n- Manual approval gates for production\n- Artifact versioning\n\n## 5. Deployment Procedure\nStep-by-step deployment process:\n1. Pre-deployment checklist\n2. Database migrations\n3. Deployment commands\n4. Post-deployment verification\n5. Smoke tests\n\n${includeRollback ? `## 6. Rollback Procedures\n- Immediate rollback (< 5 min)\n- Database rollback considerations\n- Feature flag emergency shutoff\n- Communication template\n` : ''}\n\n## 7. Troubleshooting\n- Common issues and solutions\n- Debug commands\n- Log locations\n- Escalation path\n\nTARGET PLATFORM: ${platform}\nCI PLATFORM: ${ciPlatform}\n\nIMPORTANT:\n- Include actual code/config examples, not just descriptions\n- Make commands copy-paste ready\n- Add checklist items with [ ] for verification steps\n- Include specific commands for the target platform`;\n\n const userMessage = `Create a deployment runbook for this project:\n\n${requirements ? `Requirements/Context:\\n${requirements.substring(0, 5000)}\\n` : ''}\n${deploymentContext ? `\\n---\\n${deploymentContext}` : 'No existing deployment files found. Generate complete configurations from scratch.'}\n\nTarget Platform: ${platform}\nCI Platform: ${ciPlatform}\nEnvironments: ${environments.join(', ')}\n\nGenerate a comprehensive, actionable deployment runbook.`;\n\n try {\n const result = await createCompletion({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 10000, // Large output for comprehensive runbook\n });\n\n const totalTokens = result.inputTokens + result.outputTokens;\n\n // Auto-save output\n const defaults = getToolDefaults('generate_deployment_runbook');\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_deployment_runbook',\n category: defaults.category,\n filename: defaults.filename,\n content: result.text,\n format: 'md',\n inputs: [platform, ciPlatform, ...environments],\n tokensUsed: totalTokens,\n });\n\n const discoveryNote =\n discoveredFiles.length > 0\n ? `\\n\\n---\\n🔍 **Discovered ${discoveredFiles.length} deployment file(s):** ${discoveredFiles.map((f) => f.relativePath).join(', ')}`\n : '\\n\\n---\\n⚠️ **No existing deployment files found.** Runbook generated from scratch.';\n\n return markdownResult(result.text + discoveryNote + formatSavedPath(saved), totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate deployment runbook: ${message}`);\n }\n },\n\n requiredScope: 'tools:generate_deployment_runbook',\n};\n","/**\n * Changelog Generator Module\n *\n * Generates formatted changelogs and release notes from diff data.\n * Supports markdown output with configurable detail levels.\n */\n\nimport type { ChangeSummary, ChangeItem, ModifiedItem, FieldChange, AuditEvent } from './audit-log.js';\nimport { queryAuditEvents } from './audit-log.js';\nimport { loadFromCache, getAllCachedVersions, getPreviousVersion } from './cache-manager.js';\nimport { diffBacklogs, getScopeSummary, type BacklogOutput } from './diff-engine.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ChangelogOptions {\n includeEstimates: boolean;\n includeAcceptanceCriteria: boolean;\n groupByCategory: boolean;\n detailLevel: 'summary' | 'detailed' | 'comprehensive';\n format: 'markdown' | 'json';\n audienceType: 'technical' | 'stakeholder' | 'executive';\n}\n\nexport interface ChangelogEntry {\n version: string;\n date: string;\n summary: {\n added: number;\n removed: number;\n modified: number;\n totalPointsDelta: number;\n };\n highlights: string[];\n warnings: string[];\n sections: ChangelogSection[];\n}\n\nexport interface ChangelogSection {\n title: string;\n icon: string;\n items: string[];\n}\n\nexport interface ReleaseNotes {\n version: string;\n date: string;\n title: string;\n overview: string;\n highlights: string[];\n breaking: string[];\n newFeatures: string[];\n improvements: string[];\n bugFixes: string[];\n techDebt: string[];\n security: string[];\n}\n\n// ============================================================================\n// Default Options\n// ============================================================================\n\nconst DEFAULT_OPTIONS: ChangelogOptions = {\n includeEstimates: true,\n includeAcceptanceCriteria: false,\n groupByCategory: true,\n detailLevel: 'detailed',\n format: 'markdown',\n audienceType: 'technical',\n};\n\n// ============================================================================\n// Emoji Mapping\n// ============================================================================\n\nconst CATEGORY_ICONS: Record<string, string> = {\n features: '✨',\n api: '🔌',\n infrastructure: '🏗️',\n testing: '🧪',\n 'tech-debt': '🔧',\n security: '🔒',\n frontend: '🎨',\n default: '📋',\n};\n\nconst PRIORITY_ICONS: Record<string, string> = {\n critical: '🔴',\n high: '🟠',\n medium: '🟡',\n low: '🟢',\n};\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get icon for a category\n */\nfunction getCategoryIcon(category: string | undefined): string {\n return CATEGORY_ICONS[category || 'default'] || CATEGORY_ICONS.default;\n}\n\n/**\n * Get icon for a priority\n */\nfunction getPriorityIcon(priority: string | undefined): string {\n return PRIORITY_ICONS[priority || 'medium'] || PRIORITY_ICONS.medium;\n}\n\n/**\n * Format a change item as a bullet point\n */\nfunction formatChangeItem(item: ChangeItem, options: ChangelogOptions): string {\n let line = `- ${item.title}`;\n\n if (options.includeEstimates && item.estimate) {\n line += ` (${item.estimate} pts)`;\n }\n\n if (options.detailLevel === 'comprehensive' && item.priority) {\n line += ` ${getPriorityIcon(item.priority)}`;\n }\n\n return line;\n}\n\n/**\n * Format field changes for a modified item\n */\nfunction formatFieldChanges(changes: FieldChange[]): string[] {\n return changes.map((change) => {\n const arrow = '→';\n if (change.significance === 'critical' || change.significance === 'high') {\n return ` - **${change.field}**: ${change.oldValue} ${arrow} ${change.newValue} ⚠️`;\n }\n return ` - ${change.field}: ${change.oldValue} ${arrow} ${change.newValue}`;\n });\n}\n\n/**\n * Group items by category\n */\nfunction groupByCategory(items: ChangeItem[]): Record<string, ChangeItem[]> {\n const groups: Record<string, ChangeItem[]> = {};\n\n for (const item of items) {\n const category = item.category || 'uncategorized';\n if (!groups[category]) {\n groups[category] = [];\n }\n groups[category].push(item);\n }\n\n return groups;\n}\n\n/**\n * Generate highlights from changes\n */\nfunction generateHighlights(changes: ChangeSummary): string[] {\n const highlights: string[] = [];\n\n if (changes.added > 0) {\n highlights.push(`Added ${changes.added} new item${changes.added > 1 ? 's' : ''}`);\n }\n\n if (changes.modified > 0) {\n highlights.push(`Modified ${changes.modified} existing item${changes.modified > 1 ? 's' : ''}`);\n }\n\n if (changes.pointsDelta && changes.pointsDelta !== 0) {\n const direction = changes.pointsDelta > 0 ? 'increased' : 'decreased';\n highlights.push(`Total scope ${direction} by ${Math.abs(changes.pointsDelta)} story points`);\n }\n\n return highlights;\n}\n\n/**\n * Generate warnings from changes\n */\nfunction generateWarnings(changes: ChangeSummary): string[] {\n const warnings: string[] = [];\n\n if (changes.hasRegressions) {\n warnings.push('⚠️ **Potential Regression**: High/critical priority items were removed');\n }\n\n if (changes.hasScopeCreep) {\n warnings.push('⚠️ **Scope Creep Detected**: Significant increase in scope or new items');\n }\n\n if (changes.hasEstimateInflation) {\n warnings.push('⚠️ **Estimate Inflation**: Total estimates increased by >20%');\n }\n\n if (changes.removed > 0) {\n warnings.push(`ℹ️ ${changes.removed} item${changes.removed > 1 ? 's were' : ' was'} removed from the backlog`);\n }\n\n return warnings;\n}\n\n// ============================================================================\n// Main Functions\n// ============================================================================\n\n/**\n * Generate a changelog from a diff\n */\nexport function generateChangelog(\n changes: ChangeSummary,\n fromVersion: string,\n toVersion: string,\n options: Partial<ChangelogOptions> = {}\n): ChangelogEntry {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n const entry: ChangelogEntry = {\n version: toVersion,\n date: new Date().toISOString().split('T')[0],\n summary: {\n added: changes.added,\n removed: changes.removed,\n modified: changes.modified,\n totalPointsDelta: changes.pointsDelta || 0,\n },\n highlights: generateHighlights(changes),\n warnings: generateWarnings(changes),\n sections: [],\n };\n\n // Added items section\n if (changes.addedItems.length > 0) {\n if (opts.groupByCategory) {\n const groups = groupByCategory(changes.addedItems);\n for (const [category, items] of Object.entries(groups)) {\n entry.sections.push({\n title: `Added - ${category.charAt(0).toUpperCase() + category.slice(1)}`,\n icon: getCategoryIcon(category),\n items: items.map((item) => formatChangeItem(item, opts)),\n });\n }\n } else {\n entry.sections.push({\n title: 'Added',\n icon: '✅',\n items: changes.addedItems.map((item) => formatChangeItem(item, opts)),\n });\n }\n }\n\n // Removed items section\n if (changes.removedItems.length > 0) {\n entry.sections.push({\n title: 'Removed',\n icon: '❌',\n items: changes.removedItems.map((item) => formatChangeItem(item, opts)),\n });\n }\n\n // Modified items section\n if (changes.modifiedItems.length > 0) {\n const modifiedFormatted: string[] = [];\n\n for (const item of changes.modifiedItems) {\n modifiedFormatted.push(formatChangeItem(item, opts));\n if (opts.detailLevel !== 'summary') {\n modifiedFormatted.push(...formatFieldChanges(item.changes));\n }\n }\n\n entry.sections.push({\n title: 'Modified',\n icon: '📝',\n items: modifiedFormatted,\n });\n }\n\n return entry;\n}\n\n/**\n * Format a changelog entry as markdown\n */\nexport function formatChangelogMarkdown(entry: ChangelogEntry): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`## Version ${entry.version}`);\n lines.push(`*${entry.date}*`);\n lines.push('');\n\n // Summary\n lines.push('### Summary');\n lines.push(`- **Added**: ${entry.summary.added}`);\n lines.push(`- **Removed**: ${entry.summary.removed}`);\n lines.push(`- **Modified**: ${entry.summary.modified}`);\n if (entry.summary.totalPointsDelta !== 0) {\n const sign = entry.summary.totalPointsDelta > 0 ? '+' : '';\n lines.push(`- **Points Delta**: ${sign}${entry.summary.totalPointsDelta}`);\n }\n lines.push('');\n\n // Highlights\n if (entry.highlights.length > 0) {\n lines.push('### Highlights');\n for (const highlight of entry.highlights) {\n lines.push(`- ${highlight}`);\n }\n lines.push('');\n }\n\n // Warnings\n if (entry.warnings.length > 0) {\n lines.push('### Warnings');\n for (const warning of entry.warnings) {\n lines.push(`- ${warning}`);\n }\n lines.push('');\n }\n\n // Sections\n for (const section of entry.sections) {\n lines.push(`### ${section.icon} ${section.title}`);\n for (const item of section.items) {\n lines.push(item);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate release notes for stakeholders (non-technical audience)\n */\nexport function generateReleaseNotes(\n changes: ChangeSummary,\n version: string,\n projectName: string = 'Project'\n): ReleaseNotes {\n const notes: ReleaseNotes = {\n version,\n date: new Date().toISOString().split('T')[0],\n title: `${projectName} ${version} Release Notes`,\n overview: '',\n highlights: [],\n breaking: [],\n newFeatures: [],\n improvements: [],\n bugFixes: [],\n techDebt: [],\n security: [],\n };\n\n // Categorize added items\n for (const item of changes.addedItems) {\n const category = item.category?.toLowerCase() || '';\n\n if (category.includes('security')) {\n notes.security.push(item.title);\n } else if (category.includes('tech-debt') || category.includes('refactor')) {\n notes.techDebt.push(item.title);\n } else if (category.includes('bug') || category.includes('fix')) {\n notes.bugFixes.push(item.title);\n } else {\n notes.newFeatures.push(item.title);\n }\n }\n\n // Modified items are improvements\n for (const item of changes.modifiedItems) {\n notes.improvements.push(item.title);\n }\n\n // Removed critical items are breaking changes\n for (const item of changes.removedItems) {\n if (item.priority === 'critical' || item.priority === 'high') {\n notes.breaking.push(`Removed: ${item.title}`);\n }\n }\n\n // Generate highlights\n if (notes.newFeatures.length > 0) {\n notes.highlights.push(`${notes.newFeatures.length} new features added`);\n }\n if (notes.security.length > 0) {\n notes.highlights.push(`${notes.security.length} security improvements`);\n }\n if (notes.bugFixes.length > 0) {\n notes.highlights.push(`${notes.bugFixes.length} bug fixes`);\n }\n\n // Generate overview\n notes.overview = `This release includes ${changes.added} new items, ${changes.modified} improvements, and ${changes.removed} removals.`;\n\n if (changes.hasRegressions) {\n notes.overview += ' Please review the breaking changes section carefully.';\n }\n\n return notes;\n}\n\n/**\n * Format release notes as markdown\n */\nexport function formatReleaseNotesMarkdown(notes: ReleaseNotes): string {\n const lines: string[] = [];\n\n lines.push(`# ${notes.title}`);\n lines.push(`*Released: ${notes.date}*`);\n lines.push('');\n lines.push(notes.overview);\n lines.push('');\n\n if (notes.highlights.length > 0) {\n lines.push('## Highlights');\n for (const h of notes.highlights) {\n lines.push(`- ${h}`);\n }\n lines.push('');\n }\n\n if (notes.breaking.length > 0) {\n lines.push('## ⚠️ Breaking Changes');\n for (const item of notes.breaking) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n if (notes.newFeatures.length > 0) {\n lines.push('## ✨ New Features');\n for (const item of notes.newFeatures) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n if (notes.improvements.length > 0) {\n lines.push('## 📈 Improvements');\n for (const item of notes.improvements) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n if (notes.bugFixes.length > 0) {\n lines.push('## 🐛 Bug Fixes');\n for (const item of notes.bugFixes) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n if (notes.security.length > 0) {\n lines.push('## 🔒 Security');\n for (const item of notes.security) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n if (notes.techDebt.length > 0) {\n lines.push('## 🔧 Technical Improvements');\n for (const item of notes.techDebt) {\n lines.push(`- ${item}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate a full changelog from version history\n */\nexport function generateFullChangelog(\n projectRoot: string,\n category: string,\n filename: string,\n options: Partial<ChangelogOptions> = {}\n): string {\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length < 2) {\n return '# Changelog\\n\\nNo version history available yet.';\n }\n\n const entries: string[] = ['# Changelog\\n'];\n\n for (let i = versions.length - 1; i > 0; i--) {\n const toVersion = versions[i];\n const fromVersion = versions[i - 1];\n\n const oldDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, fromVersion);\n const newDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, toVersion);\n\n if (oldDoc && newDoc) {\n const changes = diffBacklogs(oldDoc.data, newDoc.data);\n const entry = generateChangelog(changes, fromVersion, toVersion, options);\n entries.push(formatChangelogMarkdown(entry));\n entries.push('---\\n');\n }\n }\n\n // Add initial version\n entries.push(`## Version ${versions[0]}\\n*Initial release*\\n`);\n\n return entries.join('\\n');\n}\n\n/**\n * Generate scope trend report\n */\nexport function generateScopeTrendReport(\n projectRoot: string,\n category: string,\n filename: string\n): string {\n const versions = getAllCachedVersions(projectRoot, category, filename);\n const lines: string[] = ['# Scope Trend Report\\n'];\n\n if (versions.length < 2) {\n lines.push('Not enough version history for trend analysis.');\n return lines.join('\\n');\n }\n\n lines.push('| Version | Issues | Tasks | Points | Delta |');\n lines.push('|---------|--------|-------|--------|-------|');\n\n let previousPoints = 0;\n\n for (const version of versions) {\n const doc = loadFromCache<BacklogOutput>(projectRoot, category, filename, version);\n if (doc) {\n const summary = getScopeSummary(doc.data);\n const delta = previousPoints > 0 ? summary.totalPoints - previousPoints : 0;\n const deltaStr = delta === 0 ? '-' : (delta > 0 ? `+${delta}` : `${delta}`);\n\n lines.push(\n `| ${version} | ${summary.issues} | ${summary.tasks} | ${summary.totalPoints} | ${deltaStr} |`\n );\n\n previousPoints = summary.totalPoints;\n }\n }\n\n lines.push('');\n\n // Add warnings\n const latestVersion = versions[versions.length - 1];\n const firstVersion = versions[0];\n const latestDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, latestVersion);\n const firstDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, firstVersion);\n\n if (latestDoc && firstDoc) {\n const latestPoints = getScopeSummary(latestDoc.data).totalPoints;\n const firstPoints = getScopeSummary(firstDoc.data).totalPoints;\n const totalGrowth = ((latestPoints - firstPoints) / firstPoints) * 100;\n\n if (totalGrowth > 50) {\n lines.push(`⚠️ **Warning**: Scope has grown by ${totalGrowth.toFixed(1)}% since first version.`);\n } else if (totalGrowth > 20) {\n lines.push(`ℹ️ **Note**: Scope has grown by ${totalGrowth.toFixed(1)}% since first version.`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate audit summary from recent events\n */\nexport function generateAuditSummary(projectRoot: string, daysBack: number = 7): string {\n const startDate = new Date();\n startDate.setDate(startDate.getDate() - daysBack);\n\n const events = queryAuditEvents(projectRoot, {\n startDate: startDate.toISOString(),\n });\n\n const lines: string[] = [`# Audit Summary (Last ${daysBack} Days)\\n`];\n\n if (events.length === 0) {\n lines.push('No audit events in this period.');\n return lines.join('\\n');\n }\n\n // Summary stats\n const byType: Record<string, number> = {};\n const byDoc: Record<string, number> = {};\n let totalTokens = 0;\n\n for (const event of events) {\n byType[event.eventType] = (byType[event.eventType] || 0) + 1;\n byDoc[event.documentType] = (byDoc[event.documentType] || 0) + 1;\n totalTokens += event.tokensUsed || 0;\n }\n\n lines.push('## Summary');\n lines.push(`- **Total Events**: ${events.length}`);\n lines.push(`- **Total Tokens Used**: ${totalTokens.toLocaleString()}`);\n lines.push('');\n\n lines.push('### By Event Type');\n for (const [type, count] of Object.entries(byType)) {\n lines.push(`- ${type}: ${count}`);\n }\n lines.push('');\n\n lines.push('### By Document Type');\n for (const [doc, count] of Object.entries(byDoc)) {\n lines.push(`- ${doc}: ${count}`);\n }\n lines.push('');\n\n // Recent activity\n lines.push('## Recent Activity');\n const recent = events.slice(0, 10);\n for (const event of recent) {\n const date = new Date(event.timestamp).toLocaleString();\n lines.push(`- [${date}] ${event.eventType.toUpperCase()}: ${event.documentType} (v${event.version})`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Tracking Module Exports\n *\n * Provides change tracking, audit logging, and changelog generation\n * for VasperaPM document management.\n */\n\n// Audit logging\nexport {\n appendAuditEvent,\n readAuditEvents,\n queryAuditEvents,\n getDocumentHistory,\n getLastEvent,\n getAuditSummary,\n getAuditLogPath,\n computeHash,\n type AuditEvent,\n type ChangeSummary,\n type ChangeItem,\n type ModifiedItem,\n type FieldChange,\n} from './audit-log.js';\n\n// Cache management\nexport {\n saveToCache,\n loadFromCache,\n getLatestCachedVersion,\n getAllCachedVersions,\n getPreviousVersion,\n getCacheStats,\n pruneCache,\n clearCategoryCache,\n getCacheDir,\n getCacheFilePath,\n type CachedDocument,\n type CacheStats,\n} from './cache-manager.js';\n\n// Diff engine\nexport {\n diffBacklogs,\n diffIssue,\n detectRegressions,\n trackEstimateInflation,\n findTopInflators,\n getScopeSummary,\n flattenIssues,\n sumEstimates,\n countTasks,\n type BacklogOutput,\n type BacklogEpic,\n type BacklogIssue,\n} from './diff-engine.js';\n\n// Changelog generation\nexport {\n generateChangelog,\n formatChangelogMarkdown,\n generateReleaseNotes,\n formatReleaseNotesMarkdown,\n generateFullChangelog,\n generateScopeTrendReport,\n generateAuditSummary,\n type ChangelogOptions,\n type ChangelogEntry,\n type ChangelogSection,\n type ReleaseNotes,\n} from './changelog-generator.js';\n","/**\n * Generate Changelog Tool\n *\n * Generates changelogs from cached document versions.\n * Supports backlog diff, release notes, and audit summaries.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport {\n loadFromCache,\n getAllCachedVersions,\n diffBacklogs,\n generateChangelog,\n formatChangelogMarkdown,\n generateReleaseNotes,\n formatReleaseNotesMarkdown,\n generateFullChangelog,\n generateScopeTrendReport,\n generateAuditSummary,\n getCacheStats,\n type BacklogOutput,\n} from '../tracking/index.js';\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const generateChangelogTool: ToolDefinition = {\n tool: {\n name: 'generate_changelog',\n description: `Generate changelogs and release notes from VasperaPM document history.\n\nSupports multiple output types:\n- **changelog**: Detailed diff between two versions showing added/removed/modified items\n- **release_notes**: Stakeholder-friendly release notes\n- **full_history**: Complete changelog across all versions\n- **scope_trend**: Track scope changes over time (scope creep detection)\n- **audit_summary**: Recent activity summary from audit log\n\nRequires previous tool runs with tracking enabled. Caches are stored in docs/vasperaPM/.cache/\n\nBest for: Sprint reviews, release planning, stakeholder communication, scope management.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n outputType: {\n type: 'string',\n enum: ['changelog', 'release_notes', 'full_history', 'scope_trend', 'audit_summary'],\n default: 'changelog',\n description: 'Type of output to generate',\n },\n category: {\n type: 'string',\n default: 'backlog',\n description: 'Document category (e.g., backlog, prd, architecture)',\n },\n filename: {\n type: 'string',\n default: 'complete_backlog',\n description: 'Base filename to compare versions of',\n },\n fromVersion: {\n type: 'string',\n description: 'Starting version (defaults to previous version)',\n },\n toVersion: {\n type: 'string',\n description: 'Ending version (defaults to latest)',\n },\n projectName: {\n type: 'string',\n default: 'Project',\n description: 'Project name for release notes title',\n },\n daysBack: {\n type: 'number',\n default: 7,\n description: 'Days to look back for audit summary',\n },\n detailLevel: {\n type: 'string',\n enum: ['summary', 'detailed', 'comprehensive'],\n default: 'detailed',\n description: 'Level of detail in changelog',\n },\n groupByCategory: {\n type: 'boolean',\n default: true,\n description: 'Group changes by category',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const outputType = (args.outputType as string) || 'changelog';\n const category = (args.category as string) || 'backlog';\n const filename = (args.filename as string) || 'complete_backlog';\n const projectName = (args.projectName as string) || 'Project';\n const daysBack = (args.daysBack as number) || 7;\n const detailLevel = (args.detailLevel as 'summary' | 'detailed' | 'comprehensive') || 'detailed';\n const groupByCategory = args.groupByCategory !== false;\n\n // Get cache stats first\n const cacheStats = getCacheStats(projectRoot);\n\n if (cacheStats.totalFiles === 0) {\n return errorResult(\n 'No cached documents found. Run tools with tracking enabled first.\\n\\n' +\n 'Example: Run generate_complete_backlog to create the first cached version.'\n );\n }\n\n let output: string;\n let tokensUsed = 0; // No AI calls, so 0 tokens\n\n try {\n switch (outputType) {\n case 'changelog': {\n // Get versions\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length < 2) {\n return errorResult(\n `Not enough versions to generate changelog. Found ${versions.length} version(s).\\n` +\n 'Run the tool again to create a new version for comparison.'\n );\n }\n\n // Determine versions to compare\n const toVersion = (args.toVersion as string) || versions[versions.length - 1];\n const fromVersion = (args.fromVersion as string) || versions[versions.length - 2];\n\n // Load documents\n const oldDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, fromVersion);\n const newDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, toVersion);\n\n if (!oldDoc || !newDoc) {\n return errorResult(`Could not load cached versions. From: ${fromVersion}, To: ${toVersion}`);\n }\n\n // Generate diff\n const changes = diffBacklogs(oldDoc.data, newDoc.data);\n const changelogEntry = generateChangelog(changes, fromVersion, toVersion, {\n detailLevel,\n groupByCategory,\n includeEstimates: true,\n includeAcceptanceCriteria: detailLevel === 'comprehensive',\n format: 'markdown',\n audienceType: 'technical',\n });\n\n output = `# Changelog: ${filename}\\n\\n`;\n output += `**Comparing:** v${fromVersion} → v${toVersion}\\n\\n`;\n output += formatChangelogMarkdown(changelogEntry);\n\n // Add warnings section if any flags\n if (changes.hasRegressions || changes.hasScopeCreep || changes.hasEstimateInflation) {\n output += '\\n---\\n\\n## Alerts\\n\\n';\n if (changes.hasRegressions) {\n output += '⚠️ **Regression Risk**: High/critical priority items were removed. Please verify these are intentional.\\n\\n';\n }\n if (changes.hasScopeCreep) {\n output += '⚠️ **Scope Creep**: Significant scope increase detected (>10% or 3+ new items).\\n\\n';\n }\n if (changes.hasEstimateInflation) {\n output += '⚠️ **Estimate Inflation**: Total estimates increased by >20%.\\n\\n';\n }\n }\n break;\n }\n\n case 'release_notes': {\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length < 2) {\n return errorResult('Need at least 2 versions to generate release notes.');\n }\n\n const toVersion = (args.toVersion as string) || versions[versions.length - 1];\n const fromVersion = (args.fromVersion as string) || versions[versions.length - 2];\n\n const oldDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, fromVersion);\n const newDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, toVersion);\n\n if (!oldDoc || !newDoc) {\n return errorResult('Could not load cached versions for release notes.');\n }\n\n const changes = diffBacklogs(oldDoc.data, newDoc.data);\n const releaseNotes = generateReleaseNotes(changes, toVersion, projectName);\n\n output = formatReleaseNotesMarkdown(releaseNotes);\n break;\n }\n\n case 'full_history': {\n output = generateFullChangelog(projectRoot, category, filename, {\n detailLevel,\n groupByCategory,\n includeEstimates: true,\n includeAcceptanceCriteria: false,\n format: 'markdown',\n audienceType: 'technical',\n });\n break;\n }\n\n case 'scope_trend': {\n output = generateScopeTrendReport(projectRoot, category, filename);\n break;\n }\n\n case 'audit_summary': {\n output = generateAuditSummary(projectRoot, daysBack);\n break;\n }\n\n default:\n return errorResult(`Unknown output type: ${outputType}`);\n }\n\n // Add cache stats footer\n output += '\\n\\n---\\n\\n';\n output += '## Cache Statistics\\n\\n';\n output += `- **Total cached files**: ${cacheStats.totalFiles}\\n`;\n output += `- **Total size**: ${(cacheStats.totalSizeBytes / 1024).toFixed(2)} KB\\n`;\n if (cacheStats.byCategory) {\n output += '- **By category**: ' + Object.entries(cacheStats.byCategory)\n .map(([cat, count]) => `${cat} (${count})`)\n .join(', ') + '\\n';\n }\n\n // Save output\n const defaults = getToolDefaults('generate_changelog') || { category: 'changelog', filename: 'changelog' };\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_changelog',\n category: 'changelog' as any, // Using 'changelog' category\n filename: `${outputType}_${filename}`,\n content: output,\n format: 'md',\n inputs: [outputType, category, filename],\n tokensUsed,\n skipTracking: true, // Don't track changelog generation itself\n });\n\n return markdownResult(output + formatSavedPath(saved), tokensUsed);\n\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Failed to generate changelog: ${message}`);\n }\n },\n\n requiredScope: 'tools:generate_changelog',\n};\n","/**\n * Detect Regressions Tool\n *\n * Proactively checks for accidentally removed requirements.\n * Compares current backlog against a baseline to find missing critical items.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, getToolDefaults, formatSavedPath } from '../output/index.js';\nimport {\n loadFromCache,\n getAllCachedVersions,\n detectRegressions as detectRegressionsCore,\n getScopeSummary,\n type BacklogOutput,\n type ChangeItem,\n} from '../tracking/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface Regression {\n item: ChangeItem;\n lastSeenVersion: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n possibleReason?: string;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction getSeverity(priority?: string): Regression['severity'] {\n switch (priority) {\n case 'critical':\n return 'critical';\n case 'high':\n return 'high';\n case 'medium':\n return 'medium';\n default:\n return 'low';\n }\n}\n\nfunction inferPossibleReason(item: ChangeItem): string {\n // Simple heuristics for possible reasons\n if (item.category === 'tech-debt') {\n return 'Tech debt items may be deprioritized';\n }\n if (item.category === 'testing') {\n return 'Testing items may have been merged with feature stories';\n }\n if (item.category === 'security') {\n return 'Security items may have been moved to a separate epic';\n }\n return 'Item may have been completed, merged, or deprioritized';\n}\n\nfunction formatRegressionsMarkdown(\n regressions: Regression[],\n baseline: string,\n current: string,\n baselineSummary: ReturnType<typeof getScopeSummary>,\n currentSummary: ReturnType<typeof getScopeSummary>\n): string {\n let output = '# Regression Detection Report\\n\\n';\n\n output += `**Baseline:** v${baseline} | **Current:** v${current}\\n`;\n output += `**Analysis Date:** ${new Date().toISOString()}\\n\\n`;\n\n // Executive Summary\n output += '## Executive Summary\\n\\n';\n\n const criticalCount = regressions.filter((r) => r.severity === 'critical').length;\n const highCount = regressions.filter((r) => r.severity === 'high').length;\n\n if (regressions.length === 0) {\n output += '✅ **No regressions detected.** All baseline items are present in the current version.\\n\\n';\n } else {\n output += `⚠️ **${regressions.length} items from baseline are missing in current version.**\\n\\n`;\n\n if (criticalCount > 0 || highCount > 0) {\n output += `🔴 **Action Required:** ${criticalCount} critical and ${highCount} high-priority items need review.\\n\\n`;\n }\n }\n\n // Scope Comparison\n output += '## Scope Comparison\\n\\n';\n output += '| Metric | Baseline | Current | Delta |\\n';\n output += '|--------|----------|---------|-------|\\n';\n output += `| Epics | ${baselineSummary.epics} | ${currentSummary.epics} | ${currentSummary.epics - baselineSummary.epics >= 0 ? '+' : ''}${currentSummary.epics - baselineSummary.epics} |\\n`;\n output += `| Issues | ${baselineSummary.issues} | ${currentSummary.issues} | ${currentSummary.issues - baselineSummary.issues >= 0 ? '+' : ''}${currentSummary.issues - baselineSummary.issues} |\\n`;\n output += `| Tasks | ${baselineSummary.tasks} | ${currentSummary.tasks} | ${currentSummary.tasks - baselineSummary.tasks >= 0 ? '+' : ''}${currentSummary.tasks - baselineSummary.tasks} |\\n`;\n output += `| Total Points | ${baselineSummary.totalPoints} | ${currentSummary.totalPoints} | ${currentSummary.totalPoints - baselineSummary.totalPoints >= 0 ? '+' : ''}${currentSummary.totalPoints - baselineSummary.totalPoints} |\\n\\n`;\n\n if (regressions.length === 0) {\n return output;\n }\n\n // Regressions by Severity\n output += '## Missing Items\\n\\n';\n\n // Critical\n const critical = regressions.filter((r) => r.severity === 'critical');\n if (critical.length > 0) {\n output += '### 🔴 Critical Priority\\n\\n';\n output += '| ID | Title | Category | Points | Possible Reason |\\n';\n output += '|----|-------|----------|--------|----------------|\\n';\n for (const reg of critical) {\n output += `| ${reg.item.id} | ${reg.item.title} | ${reg.item.category || '-'} | ${reg.item.estimate || '-'} | ${reg.possibleReason} |\\n`;\n }\n output += '\\n';\n }\n\n // High\n const high = regressions.filter((r) => r.severity === 'high');\n if (high.length > 0) {\n output += '### 🟠 High Priority\\n\\n';\n output += '| ID | Title | Category | Points | Possible Reason |\\n';\n output += '|----|-------|----------|--------|----------------|\\n';\n for (const reg of high) {\n output += `| ${reg.item.id} | ${reg.item.title} | ${reg.item.category || '-'} | ${reg.item.estimate || '-'} | ${reg.possibleReason} |\\n`;\n }\n output += '\\n';\n }\n\n // Medium\n const medium = regressions.filter((r) => r.severity === 'medium');\n if (medium.length > 0) {\n output += '### 🟡 Medium Priority\\n\\n';\n output += '| ID | Title | Category | Points | Possible Reason |\\n';\n output += '|----|-------|----------|--------|----------------|\\n';\n for (const reg of medium) {\n output += `| ${reg.item.id} | ${reg.item.title} | ${reg.item.category || '-'} | ${reg.item.estimate || '-'} | ${reg.possibleReason} |\\n`;\n }\n output += '\\n';\n }\n\n // Low\n const low = regressions.filter((r) => r.severity === 'low');\n if (low.length > 0) {\n output += '### 🟢 Low Priority\\n\\n';\n output += '| ID | Title | Category | Points | Possible Reason |\\n';\n output += '|----|-------|----------|--------|----------------|\\n';\n for (const reg of low) {\n output += `| ${reg.item.id} | ${reg.item.title} | ${reg.item.category || '-'} | ${reg.item.estimate || '-'} | ${reg.possibleReason} |\\n`;\n }\n output += '\\n';\n }\n\n // Recommendations\n output += '## Recommendations\\n\\n';\n output += '1. **Review critical/high items** - Verify these removals are intentional\\n';\n output += '2. **Update PRD** - If items were intentionally removed, document the reason\\n';\n output += '3. **Check for merges** - Some items may have been consolidated into other stories\\n';\n output += '4. **Audit trail** - Run `generate_changelog` to see when items were removed\\n\\n';\n\n return output;\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const detectRegressionsTool: ToolDefinition = {\n tool: {\n name: 'detect_regressions',\n description: `Proactively check for accidentally removed requirements.\n\nCompares the current backlog against a baseline version to find missing items.\nFlags critical and high-priority items that may have been unintentionally removed.\n\nUse Cases:\n- Pre-sync validation before pushing to ADO/Jira\n- Sprint planning review\n- Compliance audits\n- PRD drift detection\n\nBest for: Preventing accidental scope reduction and ensuring requirements coverage.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n baseline: {\n type: 'string',\n description: 'Baseline version to compare against (default: v1.0 or first version)',\n },\n current: {\n type: 'string',\n description: 'Current version to check (default: latest)',\n },\n category: {\n type: 'string',\n default: 'backlog',\n description: 'Document category (e.g., backlog, prd)',\n },\n filename: {\n type: 'string',\n default: 'complete_backlog',\n description: 'Base filename to check',\n },\n criticalOnly: {\n type: 'boolean',\n default: false,\n description: 'Only flag critical/high priority items',\n },\n failOnRegressions: {\n type: 'boolean',\n default: false,\n description: 'Return error if regressions found (for CI integration)',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const category = (args.category as string) || 'backlog';\n const filename = (args.filename as string) || 'complete_backlog';\n const criticalOnly = (args.criticalOnly as boolean) || false;\n const failOnRegressions = (args.failOnRegressions as boolean) || false;\n\n // Get available versions\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length === 0) {\n return errorResult(\n 'No cached versions found. Run generate_complete_backlog first to create a baseline.'\n );\n }\n\n if (versions.length === 1) {\n return markdownResult(\n '# Regression Detection Report\\n\\n' +\n '✅ Only one version exists. No regression comparison possible yet.\\n\\n' +\n 'Run generate_complete_backlog again to create a new version for comparison.',\n 0\n );\n }\n\n // Determine versions to compare\n const baseline = (args.baseline as string) || versions[0]; // First version\n const current = (args.current as string) || versions[versions.length - 1]; // Latest\n\n // Load documents\n const baselineDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, baseline);\n const currentDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, current);\n\n if (!baselineDoc) {\n return errorResult(`Could not load baseline version: v${baseline}`);\n }\n\n if (!currentDoc) {\n return errorResult(`Could not load current version: v${current}`);\n }\n\n // Detect regressions\n const removedItems = detectRegressionsCore(baselineDoc.data, currentDoc.data, criticalOnly);\n\n // Convert to regressions with severity\n const regressions: Regression[] = removedItems.map((item) => ({\n item,\n lastSeenVersion: baseline,\n severity: getSeverity(item.priority),\n possibleReason: inferPossibleReason(item),\n }));\n\n // Get scope summaries\n const baselineSummary = getScopeSummary(baselineDoc.data);\n const currentSummary = getScopeSummary(currentDoc.data);\n\n // Generate report\n const output = formatRegressionsMarkdown(\n regressions,\n baseline,\n current,\n baselineSummary,\n currentSummary\n );\n\n // Save output\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'detect_regressions',\n category: 'changelog' as any,\n filename: 'regression_report',\n content: output,\n format: 'md',\n inputs: [baseline, current, criticalOnly.toString()],\n tokensUsed: 0,\n skipTracking: true,\n });\n\n // Check if should fail\n const criticalCount = regressions.filter((r) => r.severity === 'critical').length;\n const highCount = regressions.filter((r) => r.severity === 'high').length;\n\n if (failOnRegressions && (criticalCount > 0 || highCount > 0)) {\n return {\n content: [\n {\n type: 'text' as const,\n text:\n `❌ **Regression Check Failed**\\n\\n` +\n `Found ${criticalCount} critical and ${highCount} high-priority regressions.\\n\\n` +\n output +\n formatSavedPath(saved),\n },\n ],\n isError: true,\n };\n }\n\n return markdownResult(output + formatSavedPath(saved), 0);\n },\n\n requiredScope: 'tools:detect_regressions',\n};\n","/**\n * Generate Sprint Report Tool\n *\n * Generate sprint-focused reports showing scope changes.\n * Tracks scope creep, estimate inflation, and risk indicators.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, formatSavedPath } from '../output/index.js';\nimport {\n loadFromCache,\n getAllCachedVersions,\n diffBacklogs,\n getScopeSummary,\n queryAuditEvents,\n type BacklogOutput,\n type ChangeSummary,\n} from '../tracking/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface SprintReportData {\n period: { start: string; end: string };\n scopeAtStart: ReturnType<typeof getScopeSummary>;\n scopeAtEnd: ReturnType<typeof getScopeSummary>;\n changes: ChangeSummary;\n velocity?: {\n planned: number;\n completed: number;\n carryover: number;\n };\n risks: {\n scopeCreep: { detected: boolean; percentage: number };\n estimateInflation: { detected: boolean; percentage: number };\n regressions: { detected: boolean; count: number };\n };\n auditActivity: {\n totalEvents: number;\n creates: number;\n updates: number;\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction findVersionNearDate(\n projectRoot: string,\n category: string,\n filename: string,\n targetDate: Date\n): string | null {\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length === 0) return null;\n\n // Load each version and find the one closest to (but not after) target date\n let bestVersion: string | null = null;\n let bestTimeDiff = Infinity;\n\n for (const version of versions) {\n const doc = loadFromCache<BacklogOutput>(projectRoot, category, filename, version);\n if (doc && doc.timestamp) {\n const docDate = new Date(doc.timestamp);\n if (docDate <= targetDate) {\n const diff = targetDate.getTime() - docDate.getTime();\n if (diff < bestTimeDiff) {\n bestTimeDiff = diff;\n bestVersion = version;\n }\n }\n }\n }\n\n // If no version found before date, use first version\n return bestVersion || versions[0];\n}\n\nfunction formatSprintReportMarkdown(data: SprintReportData): string {\n let output = '# Sprint Report\\n\\n';\n\n output += `**Period:** ${data.period.start} to ${data.period.end}\\n`;\n output += `**Generated:** ${new Date().toISOString()}\\n\\n`;\n\n // Executive Summary\n output += '## Executive Summary\\n\\n';\n\n output += '| Metric | Start | End | Delta |\\n';\n output += '|--------|-------|-----|-------|\\n';\n output += `| Total Issues | ${data.scopeAtStart.issues} | ${data.scopeAtEnd.issues} | ${data.scopeAtEnd.issues - data.scopeAtStart.issues >= 0 ? '+' : ''}${data.scopeAtEnd.issues - data.scopeAtStart.issues} |\\n`;\n output += `| Total Points | ${data.scopeAtStart.totalPoints} | ${data.scopeAtEnd.totalPoints} | ${data.scopeAtEnd.totalPoints - data.scopeAtStart.totalPoints >= 0 ? '+' : ''}${data.scopeAtEnd.totalPoints - data.scopeAtStart.totalPoints} |\\n`;\n output += `| Epics | ${data.scopeAtStart.epics} | ${data.scopeAtEnd.epics} | ${data.scopeAtEnd.epics - data.scopeAtStart.epics >= 0 ? '+' : ''}${data.scopeAtEnd.epics - data.scopeAtStart.epics} |\\n`;\n output += `| Tasks | ${data.scopeAtStart.tasks} | ${data.scopeAtEnd.tasks} | ${data.scopeAtEnd.tasks - data.scopeAtStart.tasks >= 0 ? '+' : ''}${data.scopeAtEnd.tasks - data.scopeAtStart.tasks} |\\n\\n`;\n\n // Risk Indicators\n output += '## Risk Indicators\\n\\n';\n\n output += '| Risk | Status | Details |\\n';\n output += '|------|--------|--------|\\n';\n\n // Scope Creep\n if (data.risks.scopeCreep.detected) {\n output += `| Scope Creep | ⚠️ **Warning** | ${data.risks.scopeCreep.percentage.toFixed(1)}% increase |\\n`;\n } else {\n output += `| Scope Creep | ✅ OK | ${data.risks.scopeCreep.percentage.toFixed(1)}% change |\\n`;\n }\n\n // Estimate Inflation\n if (data.risks.estimateInflation.detected) {\n output += `| Estimate Inflation | ⚠️ **Warning** | ${data.risks.estimateInflation.percentage.toFixed(1)}% increase |\\n`;\n } else {\n output += `| Estimate Inflation | ✅ OK | ${data.risks.estimateInflation.percentage.toFixed(1)}% change |\\n`;\n }\n\n // Regressions\n if (data.risks.regressions.detected) {\n output += `| Regressions | 🔴 **Alert** | ${data.risks.regressions.count} items removed |\\n`;\n } else {\n output += `| Regressions | ✅ OK | No critical items removed |\\n`;\n }\n\n output += '\\n';\n\n // Scope Changes\n output += '## Scope Changes\\n\\n';\n\n // Added Items\n if (data.changes.addedItems.length > 0) {\n output += '### New Work Added\\n\\n';\n output += '| ID | Title | Category | Priority | Points |\\n';\n output += '|----|-------|----------|----------|--------|\\n';\n for (const item of data.changes.addedItems.slice(0, 10)) {\n output += `| ${item.id} | ${item.title} | ${item.category || '-'} | ${item.priority || '-'} | ${item.estimate || '-'} |\\n`;\n }\n if (data.changes.addedItems.length > 10) {\n output += `\\n*...and ${data.changes.addedItems.length - 10} more items*\\n`;\n }\n output += '\\n';\n }\n\n // Removed Items\n if (data.changes.removedItems.length > 0) {\n output += '### Removed Items\\n\\n';\n output += '| ID | Title | Category | Priority | Points |\\n';\n output += '|----|-------|----------|----------|--------|\\n';\n for (const item of data.changes.removedItems.slice(0, 10)) {\n const priorityEmoji = item.priority === 'critical' ? '🔴' : item.priority === 'high' ? '🟠' : '';\n output += `| ${item.id} | ${item.title} | ${item.category || '-'} | ${priorityEmoji} ${item.priority || '-'} | ${item.estimate || '-'} |\\n`;\n }\n if (data.changes.removedItems.length > 10) {\n output += `\\n*...and ${data.changes.removedItems.length - 10} more items*\\n`;\n }\n output += '\\n';\n }\n\n // Modified Items\n if (data.changes.modifiedItems.length > 0) {\n output += '### Modified Items\\n\\n';\n output += '| ID | Title | Changes |\\n';\n output += '|----|-------|---------|\\n';\n for (const item of data.changes.modifiedItems.slice(0, 10)) {\n const changesSummary = item.changes\n .map((c) => `${c.field}: ${c.oldValue} → **${c.newValue}**`)\n .join('; ');\n output += `| ${item.id} | ${item.title} | ${changesSummary} |\\n`;\n }\n if (data.changes.modifiedItems.length > 10) {\n output += `\\n*...and ${data.changes.modifiedItems.length - 10} more items*\\n`;\n }\n output += '\\n';\n }\n\n // Category Breakdown\n output += '## Category Breakdown\\n\\n';\n output += '| Category | Issues (Start) | Issues (End) | Points (Start) | Points (End) |\\n';\n output += '|----------|----------------|--------------|----------------|---------------|\\n';\n\n const allCategories = new Set([\n ...Object.keys(data.scopeAtStart.byCategory),\n ...Object.keys(data.scopeAtEnd.byCategory),\n ]);\n\n for (const cat of allCategories) {\n const startData = data.scopeAtStart.byCategory[cat] || { issues: 0, points: 0 };\n const endData = data.scopeAtEnd.byCategory[cat] || { issues: 0, points: 0 };\n output += `| ${cat} | ${startData.issues} | ${endData.issues} | ${startData.points} | ${endData.points} |\\n`;\n }\n output += '\\n';\n\n // Activity Summary\n output += '## Activity Summary\\n\\n';\n output += `- **Document changes**: ${data.auditActivity.totalEvents}\\n`;\n output += `- **New documents**: ${data.auditActivity.creates}\\n`;\n output += `- **Updates**: ${data.auditActivity.updates}\\n\\n`;\n\n // Recommendations\n output += '## Recommendations\\n\\n';\n\n if (data.risks.scopeCreep.detected) {\n output += `1. **Review scope increase** - ${data.risks.scopeCreep.percentage.toFixed(1)}% growth may impact delivery\\n`;\n }\n if (data.risks.estimateInflation.detected) {\n output += `2. **Investigate estimate changes** - ${data.risks.estimateInflation.percentage.toFixed(1)}% increase in story points\\n`;\n }\n if (data.risks.regressions.detected) {\n output += `3. **Verify removed items** - ${data.risks.regressions.count} items were removed, confirm this is intentional\\n`;\n }\n if (data.changes.addedItems.length > 3) {\n output += `4. **PRD alignment** - ${data.changes.addedItems.length} new items added, ensure they're documented\\n`;\n }\n if (!data.risks.scopeCreep.detected && !data.risks.estimateInflation.detected && !data.risks.regressions.detected) {\n output += '✅ No significant concerns. Scope is stable.\\n';\n }\n\n return output;\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const generateSprintReportTool: ToolDefinition = {\n tool: {\n name: 'generate_sprint_report',\n description: `Generate sprint-focused report showing scope changes over a time period.\n\nIncludes:\n- Scope comparison (start vs end)\n- Risk indicators (scope creep, estimate inflation, regressions)\n- Added/removed/modified items\n- Category breakdown\n- Recommendations\n\nBest for: Sprint reviews, stakeholder updates, planning meetings.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n sprintStart: {\n type: 'string',\n description: 'Sprint start date (ISO format, e.g., \"2026-01-10\"). Defaults to 14 days ago.',\n },\n sprintEnd: {\n type: 'string',\n description: 'Sprint end date (ISO format). Defaults to today.',\n },\n category: {\n type: 'string',\n default: 'backlog',\n description: 'Document category to analyze',\n },\n filename: {\n type: 'string',\n default: 'complete_backlog',\n description: 'Base filename to analyze',\n },\n includeVelocity: {\n type: 'boolean',\n default: false,\n description: 'Include velocity metrics (requires completion tracking)',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const category = (args.category as string) || 'backlog';\n const filename = (args.filename as string) || 'complete_backlog';\n\n // Parse dates\n const now = new Date();\n const twoWeeksAgo = new Date(now.getTime() - 14 * 24 * 60 * 60 * 1000);\n\n const sprintEnd = args.sprintEnd\n ? new Date(args.sprintEnd as string)\n : now;\n\n const sprintStart = args.sprintStart\n ? new Date(args.sprintStart as string)\n : twoWeeksAgo;\n\n // Get available versions\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length === 0) {\n return errorResult(\n 'No cached versions found. Run generate_complete_backlog first to create versions.'\n );\n }\n\n // Find versions closest to sprint start/end\n const startVersion = findVersionNearDate(projectRoot, category, filename, sprintStart) || versions[0];\n const endVersion = findVersionNearDate(projectRoot, category, filename, sprintEnd) || versions[versions.length - 1];\n\n // Load documents\n const startDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, startVersion);\n const endDoc = loadFromCache<BacklogOutput>(projectRoot, category, filename, endVersion);\n\n if (!startDoc || !endDoc) {\n return errorResult('Could not load cached versions for sprint report.');\n }\n\n // Calculate metrics\n const scopeAtStart = getScopeSummary(startDoc.data);\n const scopeAtEnd = getScopeSummary(endDoc.data);\n const changes = diffBacklogs(startDoc.data, endDoc.data);\n\n // Get audit activity for the period\n const auditEvents = queryAuditEvents(projectRoot, {\n startDate: sprintStart.toISOString(),\n endDate: sprintEnd.toISOString(),\n });\n\n const pointsDelta = scopeAtEnd.totalPoints - scopeAtStart.totalPoints;\n const pointsPercentChange = scopeAtStart.totalPoints > 0\n ? (pointsDelta / scopeAtStart.totalPoints) * 100\n : 0;\n\n // Build report data\n const reportData: SprintReportData = {\n period: {\n start: sprintStart.toISOString().split('T')[0],\n end: sprintEnd.toISOString().split('T')[0],\n },\n scopeAtStart,\n scopeAtEnd,\n changes,\n risks: {\n scopeCreep: {\n detected: changes.hasScopeCreep,\n percentage: pointsPercentChange,\n },\n estimateInflation: {\n detected: changes.hasEstimateInflation,\n percentage: pointsPercentChange,\n },\n regressions: {\n detected: changes.hasRegressions,\n count: changes.removedItems.filter(\n (item) => item.priority === 'critical' || item.priority === 'high'\n ).length,\n },\n },\n auditActivity: {\n totalEvents: auditEvents.length,\n creates: auditEvents.filter((e) => e.eventType === 'create').length,\n updates: auditEvents.filter((e) => e.eventType === 'update').length,\n },\n };\n\n // Generate report\n const output = formatSprintReportMarkdown(reportData);\n\n // Save output\n const dateStr = sprintEnd.toISOString().split('T')[0];\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'generate_sprint_report',\n category: 'changelog' as any,\n filename: `sprint_report_${dateStr}`,\n content: output,\n format: 'md',\n inputs: [sprintStart.toISOString(), sprintEnd.toISOString()],\n tokensUsed: 0,\n skipTracking: true,\n });\n\n return markdownResult(output + formatSavedPath(saved), 0);\n },\n\n requiredScope: 'tools:generate_sprint_report',\n};\n","/**\n * Track Estimates Tool\n *\n * Analyze estimate changes over time.\n * Detects estimate inflation and identifies top inflators.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, formatSavedPath } from '../output/index.js';\nimport {\n loadFromCache,\n getAllCachedVersions,\n sumEstimates,\n trackEstimateInflation,\n findTopInflators,\n getScopeSummary,\n type BacklogOutput,\n} from '../tracking/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface EstimateHistory {\n version: string;\n timestamp: string;\n total: number;\n delta: number;\n percentChange: number;\n}\n\ninterface TopInflator {\n id: string;\n title: string;\n category?: string;\n oldEstimate: number;\n newEstimate: number;\n delta: number;\n percentIncrease: number;\n}\n\ninterface CategoryEstimates {\n category: string;\n initial: number;\n current: number;\n delta: number;\n percentChange: number;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction generateEstimateChart(history: EstimateHistory[]): string {\n // Simple ASCII chart\n if (history.length === 0) return '';\n\n const maxTotal = Math.max(...history.map((h) => h.total));\n const chartWidth = 40;\n\n let chart = '```\\n';\n chart += 'Estimate History (Story Points)\\n';\n chart += '─'.repeat(chartWidth + 15) + '\\n';\n\n for (const entry of history) {\n const barLength = Math.round((entry.total / maxTotal) * chartWidth);\n const bar = '█'.repeat(barLength);\n const delta = entry.delta >= 0 ? `+${entry.delta}` : `${entry.delta}`;\n chart += `v${entry.version.padEnd(4)} │${bar.padEnd(chartWidth)} ${entry.total} (${delta})\\n`;\n }\n\n chart += '```\\n';\n return chart;\n}\n\nfunction formatEstimateReportMarkdown(\n history: EstimateHistory[],\n topInflators: TopInflator[],\n categoryEstimates: CategoryEstimates[],\n firstVersion: string,\n lastVersion: string\n): string {\n let output = '# Estimate Tracking Report\\n\\n';\n\n const firstEntry = history[0];\n const lastEntry = history[history.length - 1];\n\n output += `**Period:** v${firstVersion} → v${lastVersion}\\n`;\n output += `**Generated:** ${new Date().toISOString()}\\n\\n`;\n\n // Summary\n output += '## Summary\\n\\n';\n\n if (firstEntry && lastEntry) {\n const totalDelta = lastEntry.total - firstEntry.total;\n const totalPercent = firstEntry.total > 0 ? ((totalDelta / firstEntry.total) * 100).toFixed(1) : '0';\n\n output += '| Metric | Value |\\n';\n output += '|--------|-------|\\n';\n output += `| Initial Total | ${firstEntry.total} points |\\n`;\n output += `| Current Total | ${lastEntry.total} points |\\n`;\n output += `| Total Change | ${totalDelta >= 0 ? '+' : ''}${totalDelta} points (${totalPercent}%) |\\n`;\n output += `| Versions Tracked | ${history.length} |\\n\\n`;\n\n // Alert if significant inflation\n const percentChange = parseFloat(totalPercent);\n if (percentChange > 20) {\n output += '⚠️ **Estimate Inflation Alert**: Total estimates increased by >20%.\\n';\n output += 'This may indicate scope creep or underestimation in initial planning.\\n\\n';\n } else if (percentChange > 10) {\n output += '📊 **Note**: Estimates have increased by >10%. Consider reviewing scope.\\n\\n';\n } else if (percentChange < -10) {\n output += '📉 **Note**: Estimates have decreased significantly. Verify no critical items were removed.\\n\\n';\n } else {\n output += '✅ Estimates are within normal variance.\\n\\n';\n }\n }\n\n // History Chart\n output += '## Estimate History\\n\\n';\n output += generateEstimateChart(history);\n\n // Version-by-Version History\n output += '\\n### Version Details\\n\\n';\n output += '| Version | Timestamp | Total | Delta | % Change |\\n';\n output += '|---------|-----------|-------|-------|----------|\\n';\n\n for (const entry of history) {\n const dateStr = entry.timestamp ? new Date(entry.timestamp).toISOString().split('T')[0] : '-';\n output += `| v${entry.version} | ${dateStr} | ${entry.total} | ${entry.delta >= 0 ? '+' : ''}${entry.delta} | ${entry.percentChange.toFixed(1)}% |\\n`;\n }\n output += '\\n';\n\n // Top Inflators\n if (topInflators.length > 0) {\n output += '## Top Estimate Inflators\\n\\n';\n output += 'Items with the largest estimate increases:\\n\\n';\n output += '| ID | Title | Category | Before | After | Delta | % Increase |\\n';\n output += '|----|-------|----------|--------|-------|-------|------------|\\n';\n\n for (const inflator of topInflators.slice(0, 10)) {\n output += `| ${inflator.id} | ${inflator.title.substring(0, 40)}${inflator.title.length > 40 ? '...' : ''} | ${inflator.category || '-'} | ${inflator.oldEstimate} | ${inflator.newEstimate} | +${inflator.delta} | ${inflator.percentIncrease.toFixed(0)}% |\\n`;\n }\n output += '\\n';\n }\n\n // Category Breakdown\n if (categoryEstimates.length > 0) {\n output += '## Estimates by Category\\n\\n';\n output += '| Category | Initial | Current | Delta | % Change |\\n';\n output += '|----------|---------|---------|-------|----------|\\n';\n\n for (const cat of categoryEstimates) {\n output += `| ${cat.category} | ${cat.initial} | ${cat.current} | ${cat.delta >= 0 ? '+' : ''}${cat.delta} | ${cat.percentChange.toFixed(1)}% |\\n`;\n }\n output += '\\n';\n }\n\n // Recommendations\n output += '## Recommendations\\n\\n';\n\n if (topInflators.length > 0) {\n output += '1. **Review top inflators** - These items had the largest estimate increases\\n';\n output += '2. **Document reasons** - Add notes explaining why estimates changed\\n';\n }\n\n if (history.length > 1) {\n const totalDelta = (lastEntry?.total || 0) - (firstEntry?.total || 0);\n if (totalDelta > 0) {\n output += '3. **Validate scope** - Ensure new work is reflected in PRD/requirements\\n';\n }\n }\n\n output += '4. **Regular tracking** - Run this report after each backlog regeneration\\n';\n\n return output;\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const trackEstimatesTool: ToolDefinition = {\n tool: {\n name: 'track_estimates',\n description: `Analyze estimate changes over time across backlog versions.\n\nProvides:\n- Historical trend of total story points\n- Version-by-version changes\n- Top estimate inflators (items with largest increases)\n- Category-level breakdown\n- Inflation alerts and recommendations\n\nBest for: Sprint planning, identifying estimate drift, tracking scope creep.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n category: {\n type: 'string',\n default: 'backlog',\n description: 'Document category to analyze',\n },\n filename: {\n type: 'string',\n default: 'complete_backlog',\n description: 'Base filename to analyze',\n },\n fromVersion: {\n type: 'string',\n description: 'Starting version (default: first version)',\n },\n toVersion: {\n type: 'string',\n description: 'Ending version (default: latest)',\n },\n topInflatorsLimit: {\n type: 'number',\n default: 10,\n description: 'Number of top inflators to show',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const category = (args.category as string) || 'backlog';\n const filename = (args.filename as string) || 'complete_backlog';\n const topInflatorsLimit = (args.topInflatorsLimit as number) || 10;\n\n // Get available versions\n const versions = getAllCachedVersions(projectRoot, category, filename);\n\n if (versions.length === 0) {\n return errorResult(\n 'No cached versions found. Run generate_complete_backlog first to create versions.'\n );\n }\n\n if (versions.length === 1) {\n const doc = loadFromCache<BacklogOutput>(projectRoot, category, filename, versions[0]);\n const total = doc ? sumEstimates(doc.data) : 0;\n\n return markdownResult(\n '# Estimate Tracking Report\\n\\n' +\n '📊 Only one version exists. Historical tracking will begin after the next regeneration.\\n\\n' +\n `**Current Total:** ${total} story points\\n\\n` +\n 'Run `generate_complete_backlog` again to create a new version for comparison.',\n 0\n );\n }\n\n // Determine version range\n const fromVersion = (args.fromVersion as string) || versions[0];\n const toVersion = (args.toVersion as string) || versions[versions.length - 1];\n\n // Load all versions in range\n const startIdx = versions.indexOf(fromVersion);\n const endIdx = versions.indexOf(toVersion);\n\n if (startIdx === -1 || endIdx === -1) {\n return errorResult(`Invalid version range: ${fromVersion} to ${toVersion}`);\n }\n\n const versionRange = versions.slice(startIdx, endIdx + 1);\n\n // Build version history with timestamps\n const versionData: Array<{ version: string; backlog: BacklogOutput; timestamp: string }> = [];\n\n for (const version of versionRange) {\n const doc = loadFromCache<BacklogOutput>(projectRoot, category, filename, version);\n if (doc) {\n versionData.push({\n version,\n backlog: doc.data,\n timestamp: doc.timestamp,\n });\n }\n }\n\n if (versionData.length < 2) {\n return errorResult('Could not load enough versions for comparison.');\n }\n\n // Track estimate inflation\n const history = trackEstimateInflation(versionData);\n\n // Find top inflators (compare first vs last)\n const firstBacklog = versionData[0].backlog;\n const lastBacklog = versionData[versionData.length - 1].backlog;\n\n const rawInflators = findTopInflators(firstBacklog, lastBacklog, topInflatorsLimit);\n const topInflators: TopInflator[] = rawInflators.map((inf) => ({\n id: inf.issue.id,\n title: inf.issue.title,\n category: inf.issue.category,\n oldEstimate: inf.oldEstimate,\n newEstimate: inf.newEstimate,\n delta: inf.delta,\n percentIncrease: inf.percentIncrease,\n }));\n\n // Category breakdown\n const firstSummary = getScopeSummary(firstBacklog);\n const lastSummary = getScopeSummary(lastBacklog);\n\n const allCategories = new Set([\n ...Object.keys(firstSummary.byCategory),\n ...Object.keys(lastSummary.byCategory),\n ]);\n\n const categoryEstimates: CategoryEstimates[] = Array.from(allCategories).map((cat) => {\n const initial = firstSummary.byCategory[cat]?.points || 0;\n const current = lastSummary.byCategory[cat]?.points || 0;\n const delta = current - initial;\n const percentChange = initial > 0 ? (delta / initial) * 100 : (current > 0 ? 100 : 0);\n\n return { category: cat, initial, current, delta, percentChange };\n }).sort((a, b) => b.delta - a.delta);\n\n // Generate report\n const output = formatEstimateReportMarkdown(\n history,\n topInflators,\n categoryEstimates,\n fromVersion,\n toVersion\n );\n\n // Save output\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'track_estimates',\n category: 'changelog' as any,\n filename: 'estimate_tracking',\n content: output,\n format: 'md',\n inputs: [fromVersion, toVersion],\n tokensUsed: 0,\n skipTracking: true,\n });\n\n return markdownResult(output + formatSavedPath(saved), 0);\n },\n\n requiredScope: 'tools:track_estimates',\n};\n","/**\n * Get Audit Trail Tool\n *\n * Query the audit log for compliance and debugging.\n * Provides full traceability of all VasperaPM document changes.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from './types.js';\nimport { errorResult, markdownResult } from './types.js';\nimport type { ValidationResult } from '../middleware/auth.js';\nimport { saveToolOutput, formatSavedPath } from '../output/index.js';\nimport {\n queryAuditEvents,\n getAuditSummary,\n type AuditEvent,\n} from '../tracking/index.js';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction formatAuditEventMarkdown(event: AuditEvent): string {\n let output = '';\n\n const timestamp = new Date(event.timestamp).toISOString();\n const eventIcon = {\n create: '🆕',\n update: '📝',\n delete: '🗑️',\n sync: '🔄',\n }[event.eventType] || '📋';\n\n output += `### ${eventIcon} ${event.eventType.toUpperCase()}: ${event.documentType}\\n\\n`;\n output += `- **ID:** \\`${event.id.substring(0, 8)}...\\`\\n`;\n output += `- **Timestamp:** ${timestamp}\\n`;\n output += `- **Document:** ${event.documentPath}\\n`;\n output += `- **Version:** v${event.version}${event.previousVersion ? ` (from v${event.previousVersion})` : ''}\\n`;\n output += `- **Tool:** ${event.toolName}\\n`;\n output += `- **Tokens Used:** ${event.tokensUsed.toLocaleString()}\\n`;\n\n if (event.gitBranch || event.gitCommit) {\n output += `- **Git:** ${event.gitBranch || 'unknown'}@${event.gitCommit || 'unknown'}\\n`;\n }\n\n if (event.user) {\n output += `- **User:** ${event.user}\\n`;\n }\n\n if (event.changes) {\n const c = event.changes;\n output += `- **Changes:** +${c.added} added, -${c.removed} removed, ~${c.modified} modified\\n`;\n\n if (c.hasRegressions) {\n output += ` - ⚠️ Regression detected\\n`;\n }\n if (c.hasScopeCreep) {\n output += ` - ⚠️ Scope creep detected\\n`;\n }\n if (c.hasEstimateInflation) {\n output += ` - ⚠️ Estimate inflation detected\\n`;\n }\n }\n\n output += '\\n';\n return output;\n}\n\nfunction formatAuditSummaryMarkdown(\n summary: ReturnType<typeof getAuditSummary>,\n events: AuditEvent[],\n filters: Record<string, unknown>\n): string {\n let output = '# Audit Trail Report\\n\\n';\n\n output += `**Generated:** ${new Date().toISOString()}\\n`;\n\n // Filters applied\n const filterStr = Object.entries(filters)\n .filter(([_, v]) => v !== undefined && v !== null)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n\n if (filterStr) {\n output += `**Filters:** ${filterStr}\\n`;\n }\n output += '\\n';\n\n // Summary Statistics\n output += '## Summary Statistics\\n\\n';\n output += '| Metric | Value |\\n';\n output += '|--------|-------|\\n';\n output += `| Total Events | ${summary.totalEvents} |\\n`;\n output += `| Total Tokens Used | ${summary.totalTokensUsed.toLocaleString()} |\\n`;\n\n if (summary.firstEvent) {\n output += `| First Event | ${new Date(summary.firstEvent).toISOString().split('T')[0]} |\\n`;\n }\n if (summary.lastEvent) {\n output += `| Last Event | ${new Date(summary.lastEvent).toISOString().split('T')[0]} |\\n`;\n }\n output += '\\n';\n\n // By Event Type\n output += '### By Event Type\\n\\n';\n output += '| Type | Count |\\n';\n output += '|------|-------|\\n';\n\n for (const [type, count] of Object.entries(summary.byEventType)) {\n const icon = {\n create: '🆕',\n update: '📝',\n delete: '🗑️',\n sync: '🔄',\n }[type] || '📋';\n output += `| ${icon} ${type} | ${count} |\\n`;\n }\n output += '\\n';\n\n // By Document Type\n output += '### By Document Type\\n\\n';\n output += '| Document Type | Count |\\n';\n output += '|---------------|-------|\\n';\n\n for (const [type, count] of Object.entries(summary.byDocumentType)) {\n output += `| ${type} | ${count} |\\n`;\n }\n output += '\\n';\n\n // Event Timeline\n if (events.length > 0) {\n output += '## Event Timeline\\n\\n';\n\n // Group by date\n const byDate: Record<string, AuditEvent[]> = {};\n for (const event of events) {\n const date = new Date(event.timestamp).toISOString().split('T')[0];\n if (!byDate[date]) {\n byDate[date] = [];\n }\n byDate[date].push(event);\n }\n\n // Output by date (most recent first)\n const dates = Object.keys(byDate).sort().reverse();\n\n for (const date of dates) {\n output += `### ${date}\\n\\n`;\n\n for (const event of byDate[date]) {\n output += formatAuditEventMarkdown(event);\n }\n }\n }\n\n return output;\n}\n\n// ============================================================================\n// Tool Definition\n// ============================================================================\n\nexport const getAuditTrailTool: ToolDefinition = {\n tool: {\n name: 'get_audit_trail',\n description: `Query the audit log for compliance and debugging.\n\nProvides full traceability of all VasperaPM document changes including:\n- Event timeline (creates, updates, deletes, syncs)\n- Document changes and diff summaries\n- Git context (branch, commit)\n- Token usage tracking\n- Filtering by date, document type, event type\n\nBest for: Compliance audits, debugging, understanding document history.`,\n inputSchema: {\n type: 'object',\n properties: {\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to cwd)',\n },\n documentType: {\n type: 'string',\n description: 'Filter by document type (e.g., backlog, prd, architecture)',\n },\n documentPath: {\n type: 'string',\n description: 'Filter by document path (partial match)',\n },\n startDate: {\n type: 'string',\n description: 'Filter events after this date (ISO format)',\n },\n endDate: {\n type: 'string',\n description: 'Filter events before this date (ISO format)',\n },\n eventTypes: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['create', 'update', 'delete', 'sync'],\n },\n description: 'Filter by event types',\n },\n limit: {\n type: 'number',\n default: 50,\n description: 'Maximum number of events to return',\n },\n outputFormat: {\n type: 'string',\n enum: ['markdown', 'json'],\n default: 'markdown',\n description: 'Output format',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, _validation: ValidationResult) => {\n const projectRoot = (args.projectRoot as string) || process.cwd();\n const documentType = args.documentType as string | undefined;\n const documentPath = args.documentPath as string | undefined;\n const startDate = args.startDate as string | undefined;\n const endDate = args.endDate as string | undefined;\n const eventTypes = args.eventTypes as AuditEvent['eventType'][] | undefined;\n const limit = (args.limit as number) || 50;\n const outputFormat = (args.outputFormat as string) || 'markdown';\n\n // Get summary first\n const summary = getAuditSummary(projectRoot);\n\n if (summary.totalEvents === 0) {\n return markdownResult(\n '# Audit Trail Report\\n\\n' +\n '📭 No audit events found.\\n\\n' +\n 'The audit trail is automatically populated when you run VasperaPM tools.\\n' +\n 'Run `generate_complete_backlog` or other tools to start tracking.',\n 0\n );\n }\n\n // Query events with filters\n const events = queryAuditEvents(projectRoot, {\n documentType,\n documentPath,\n startDate,\n endDate,\n eventTypes,\n limit,\n });\n\n const filters = {\n documentType,\n documentPath,\n startDate,\n endDate,\n eventTypes: eventTypes?.join(','),\n limit,\n };\n\n let output: string;\n\n if (outputFormat === 'json') {\n const jsonOutput = {\n summary,\n filters,\n events,\n generated: new Date().toISOString(),\n };\n\n output = '```json\\n' + JSON.stringify(jsonOutput, null, 2) + '\\n```\\n';\n } else {\n output = formatAuditSummaryMarkdown(summary, events, filters);\n }\n\n // Save output\n const saved = saveToolOutput({\n projectRoot,\n toolName: 'get_audit_trail',\n category: 'changelog' as any,\n filename: 'audit_trail',\n content: output,\n format: 'md',\n inputs: Object.values(filters).filter(Boolean).map(String),\n tokensUsed: 0,\n skipTracking: true,\n });\n\n return markdownResult(output + formatSavedPath(saved), 0);\n },\n\n requiredScope: 'tools:get_audit_trail',\n};\n","/**\n * Pipeline Orchestration Types\n *\n * Defines the structure for automated pipeline execution.\n */\n\n/**\n * Available pipeline types\n */\nexport type PipelineType = 'docs-first' | 'code-first' | 'full' | 'custom';\n\n/**\n * Pipeline step status\n */\nexport type PipelineStepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';\n\n/**\n * A single step in the pipeline\n */\nexport interface PipelineStep {\n /** Unique step ID */\n id: string;\n /** Display name for the step */\n name: string;\n /** Tool to execute */\n tool: string;\n /** Arguments to pass to the tool (can reference previous step outputs) */\n args: Record<string, unknown>;\n /** Dependencies - step IDs that must complete first */\n dependsOn?: string[];\n /** Optional condition function - step is skipped if returns false */\n condition?: (context: PipelineContext) => boolean;\n /** Whether this step can be skipped if inputs unchanged */\n cacheable?: boolean;\n}\n\n/**\n * Result from a single pipeline step\n */\nexport interface PipelineStepResult {\n stepId: string;\n status: PipelineStepStatus;\n /** Time taken in milliseconds */\n duration: number;\n /** Tokens used (input + output) */\n tokensUsed?: number;\n /** Output text/data from the tool */\n output?: string;\n /** Error message if failed */\n error?: string;\n /** Output file paths */\n files?: string[];\n}\n\n/**\n * Pipeline execution context - passed between steps\n */\nexport interface PipelineContext {\n /** Project root directory */\n projectRoot: string;\n /** Results from completed steps */\n stepResults: Record<string, PipelineStepResult>;\n /** Shared data between steps */\n sharedData: Record<string, unknown>;\n /** Input files and their hashes (for incremental mode) */\n inputHashes?: Record<string, string>;\n}\n\n/**\n * Progress callback for pipeline execution\n */\nexport type PipelineProgressCallback = (event: PipelineProgressEvent) => void;\n\n/**\n * Progress event emitted during pipeline execution\n */\nexport interface PipelineProgressEvent {\n type: 'step_start' | 'step_complete' | 'step_failed' | 'step_skipped' | 'pipeline_complete';\n stepId?: string;\n stepName?: string;\n progress: {\n completed: number;\n total: number;\n percentage: number;\n };\n result?: PipelineStepResult;\n message?: string;\n}\n\n/**\n * Pipeline configuration\n */\nexport interface PipelineConfig {\n /** Pipeline identifier */\n id: string;\n /** Display name */\n name: string;\n /** Description */\n description: string;\n /** Pipeline type */\n type: PipelineType;\n /** Steps to execute */\n steps: PipelineStep[];\n /** Default arguments applied to all steps */\n defaultArgs?: Record<string, unknown>;\n}\n\n/**\n * Input for run_pipeline tool\n */\nexport interface RunPipelineInput {\n /** Pipeline type to run */\n pipeline: PipelineType;\n /** Project root path */\n projectRoot?: string;\n /** Custom steps (for 'custom' pipeline type) */\n customSteps?: PipelineStep[];\n /** Additional arguments to merge with step args */\n args?: Record<string, unknown>;\n /** Enable incremental mode (skip unchanged steps) */\n incremental?: boolean;\n /** Target platform for backlog export */\n platform?: 'jira' | 'ado' | 'linear' | 'github';\n /** Project key for tracker integration */\n projectKey?: string;\n}\n\n/**\n * Output from run_pipeline tool\n */\nexport interface RunPipelineOutput {\n /** Overall pipeline status */\n status: 'completed' | 'failed' | 'partial';\n /** Total execution time in milliseconds */\n totalDuration: number;\n /** Total tokens used */\n totalTokens: number;\n /** Results for each step */\n steps: PipelineStepResult[];\n /** Generated files */\n files: string[];\n /** Summary message */\n summary: string;\n /** Errors if any */\n errors?: string[];\n}\n\n/**\n * Pre-defined pipeline configurations\n */\nexport const PIPELINE_CONFIGS: Record<Exclude<PipelineType, 'custom'>, PipelineConfig> = {\n 'docs-first': {\n id: 'docs-first',\n name: 'Docs-First Pipeline',\n description: 'Start with PRD/requirements, generate architecture, tests, and backlog',\n type: 'docs-first',\n steps: [\n {\n id: 'review-prd',\n name: 'Review PRD',\n tool: 'review_prd',\n args: {\n reviewFocus: ['completeness', 'clarity', 'technical_feasibility'],\n strictness: 'standard',\n },\n cacheable: true,\n },\n {\n id: 'generate-architecture',\n name: 'Generate Architecture',\n tool: 'generate_architecture',\n args: {\n focus: 'fullstack',\n },\n dependsOn: ['review-prd'],\n cacheable: true,\n },\n {\n id: 'generate-test-specs',\n name: 'Generate Test Specs',\n tool: 'generate_test_specs',\n args: {\n inputType: 'prd',\n testTypes: ['unit', 'integration', 'e2e'],\n coverage: 'standard',\n },\n dependsOn: ['review-prd'],\n cacheable: true,\n },\n {\n id: 'explode-backlog',\n name: 'Generate Backlog',\n tool: 'explode_backlog',\n args: {\n format: 'markdown',\n maxStories: 20,\n },\n dependsOn: ['review-prd'],\n cacheable: true,\n },\n {\n id: 'sync-to-tracker',\n name: 'Export to Tracker',\n tool: 'sync_to_tracker',\n args: {},\n dependsOn: ['explode-backlog'],\n },\n ],\n },\n\n 'code-first': {\n id: 'code-first',\n name: 'Code-First Pipeline',\n description: 'Analyze existing code to generate PRD, architecture, and improvement backlog',\n type: 'code-first',\n steps: [\n {\n id: 'explain-codebase',\n name: 'Explain Codebase',\n tool: 'explain_codebase',\n args: {\n audience: 'pm',\n focus: ['architecture', 'features', 'business_logic'],\n detailLevel: 'detailed',\n },\n cacheable: true,\n },\n {\n id: 'infer-prd',\n name: 'Infer PRD',\n tool: 'infer_prd_from_code',\n args: {},\n dependsOn: ['explain-codebase'],\n cacheable: true,\n },\n {\n id: 'reverse-flows',\n name: 'Reverse Engineer Flows',\n tool: 'reverse_engineer_user_flows',\n args: {\n codeType: 'fullstack',\n outputFormat: 'all',\n },\n cacheable: true,\n },\n {\n id: 'suggest-refactors',\n name: 'Suggest Refactors',\n tool: 'suggest_refactors',\n args: {\n priorities: ['maintainability', 'performance'],\n riskTolerance: 'medium',\n },\n cacheable: true,\n },\n {\n id: 'dependency-audit',\n name: 'Audit Dependencies',\n tool: 'dependency_audit',\n args: {\n checkTypes: ['security', 'updates', 'maintenance'],\n severity: 'moderate',\n },\n cacheable: true,\n },\n ],\n },\n\n full: {\n id: 'full',\n name: 'Full Pipeline',\n description: 'Complete analysis: code → PRD → architecture → tests → backlog → export',\n type: 'full',\n steps: [\n // Code analysis phase\n {\n id: 'explain-codebase',\n name: 'Explain Codebase',\n tool: 'explain_codebase',\n args: {\n audience: 'pm',\n focus: ['architecture', 'features', 'business_logic'],\n detailLevel: 'detailed',\n },\n cacheable: true,\n },\n {\n id: 'infer-prd',\n name: 'Infer PRD from Code',\n tool: 'infer_prd_from_code',\n args: {},\n dependsOn: ['explain-codebase'],\n cacheable: true,\n },\n {\n id: 'reverse-flows',\n name: 'Reverse Engineer Flows',\n tool: 'reverse_engineer_user_flows',\n args: {\n codeType: 'fullstack',\n outputFormat: 'all',\n },\n cacheable: true,\n },\n // Quality gates\n {\n id: 'suggest-refactors',\n name: 'Suggest Refactors',\n tool: 'suggest_refactors',\n args: {\n priorities: ['maintainability', 'performance'],\n riskTolerance: 'medium',\n },\n cacheable: true,\n },\n {\n id: 'dependency-audit',\n name: 'Audit Dependencies',\n tool: 'dependency_audit',\n args: {\n checkTypes: ['security', 'updates', 'maintenance'],\n severity: 'moderate',\n },\n cacheable: true,\n },\n // Document generation\n {\n id: 'generate-architecture',\n name: 'Generate Architecture',\n tool: 'generate_architecture',\n args: {\n focus: 'fullstack',\n },\n dependsOn: ['infer-prd'],\n cacheable: true,\n },\n {\n id: 'generate-api-docs',\n name: 'Generate API Docs',\n tool: 'generate_api_docs',\n args: {\n format: 'both',\n includeExamples: true,\n },\n dependsOn: ['explain-codebase'],\n cacheable: true,\n },\n {\n id: 'generate-test-specs',\n name: 'Generate Test Specs',\n tool: 'generate_test_specs',\n args: {\n inputType: 'code',\n testTypes: ['unit', 'integration', 'e2e'],\n coverage: 'comprehensive',\n },\n dependsOn: ['infer-prd'],\n cacheable: true,\n },\n // Backlog generation\n {\n id: 'generate-complete-backlog',\n name: 'Generate Complete Backlog',\n tool: 'generate_complete_backlog',\n args: {\n categories: {\n features: true,\n api: true,\n infrastructure: true,\n testing: true,\n techDebt: true,\n security: true,\n frontend: true,\n },\n },\n dependsOn: [\n 'infer-prd',\n 'generate-architecture',\n 'generate-api-docs',\n 'generate-test-specs',\n 'suggest-refactors',\n 'dependency-audit',\n ],\n cacheable: true,\n },\n // Export\n {\n id: 'sync-to-tracker',\n name: 'Export to Tracker',\n tool: 'sync_to_tracker',\n args: {},\n dependsOn: ['generate-complete-backlog'],\n },\n ],\n },\n};\n","/**\n * Pipeline Executor\n *\n * Orchestrates the execution of pipeline steps, managing dependencies,\n * progress tracking, and result collection.\n */\n\nimport { createHash } from 'crypto';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolve, join } from 'path';\nimport type {\n PipelineConfig,\n PipelineStep,\n PipelineStepResult,\n PipelineContext,\n PipelineProgressCallback,\n PipelineProgressEvent,\n RunPipelineOutput,\n} from './types.js';\nimport { toolHandlers } from '../index.js';\nimport type { ValidationResult } from '../../middleware/auth.js';\n\n/**\n * Execute a pipeline configuration\n */\nexport async function executePipeline(\n config: PipelineConfig,\n context: PipelineContext,\n validation: ValidationResult,\n onProgress?: PipelineProgressCallback,\n options?: {\n incremental?: boolean;\n additionalArgs?: Record<string, unknown>;\n }\n): Promise<RunPipelineOutput> {\n const startTime = Date.now();\n const stepResults: PipelineStepResult[] = [];\n const errors: string[] = [];\n const files: string[] = [];\n let totalTokens = 0;\n\n // Build execution order respecting dependencies\n const executionOrder = buildExecutionOrder(config.steps);\n\n // Execute steps in order\n for (let i = 0; i < executionOrder.length; i++) {\n const step = executionOrder[i];\n if (!step) continue;\n\n const stepStart = Date.now();\n\n // Emit step start event\n emitProgress(onProgress, {\n type: 'step_start',\n stepId: step.id,\n stepName: step.name,\n progress: {\n completed: i,\n total: executionOrder.length,\n percentage: Math.round((i / executionOrder.length) * 100),\n },\n message: `Starting: ${step.name}`,\n });\n\n // Check if dependencies completed successfully\n const depsFailed = checkDependencies(step, context.stepResults);\n if (depsFailed) {\n const result: PipelineStepResult = {\n stepId: step.id,\n status: 'skipped',\n duration: 0,\n error: `Skipped due to failed dependency: ${depsFailed}`,\n };\n stepResults.push(result);\n context.stepResults[step.id] = result;\n\n emitProgress(onProgress, {\n type: 'step_skipped',\n stepId: step.id,\n stepName: step.name,\n progress: {\n completed: i + 1,\n total: executionOrder.length,\n percentage: Math.round(((i + 1) / executionOrder.length) * 100),\n },\n result,\n message: `Skipped: ${step.name}`,\n });\n\n continue;\n }\n\n // Check condition\n if (step.condition && !step.condition(context)) {\n const result: PipelineStepResult = {\n stepId: step.id,\n status: 'skipped',\n duration: 0,\n error: 'Condition not met',\n };\n stepResults.push(result);\n context.stepResults[step.id] = result;\n\n emitProgress(onProgress, {\n type: 'step_skipped',\n stepId: step.id,\n stepName: step.name,\n progress: {\n completed: i + 1,\n total: executionOrder.length,\n percentage: Math.round(((i + 1) / executionOrder.length) * 100),\n },\n result,\n message: `Skipped: ${step.name} (condition not met)`,\n });\n\n continue;\n }\n\n // Execute the step\n try {\n const result = await executeStep(step, context, validation, config.defaultArgs, options?.additionalArgs);\n result.duration = Date.now() - stepStart;\n\n stepResults.push(result);\n context.stepResults[step.id] = result;\n\n if (result.tokensUsed) {\n totalTokens += result.tokensUsed;\n }\n\n if (result.files) {\n files.push(...result.files);\n }\n\n emitProgress(onProgress, {\n type: 'step_complete',\n stepId: step.id,\n stepName: step.name,\n progress: {\n completed: i + 1,\n total: executionOrder.length,\n percentage: Math.round(((i + 1) / executionOrder.length) * 100),\n },\n result,\n message: `Completed: ${step.name}`,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n errors.push(`${step.name}: ${errorMessage}`);\n\n const result: PipelineStepResult = {\n stepId: step.id,\n status: 'failed',\n duration: Date.now() - stepStart,\n error: errorMessage,\n };\n\n stepResults.push(result);\n context.stepResults[step.id] = result;\n\n emitProgress(onProgress, {\n type: 'step_failed',\n stepId: step.id,\n stepName: step.name,\n progress: {\n completed: i + 1,\n total: executionOrder.length,\n percentage: Math.round(((i + 1) / executionOrder.length) * 100),\n },\n result,\n message: `Failed: ${step.name} - ${errorMessage}`,\n });\n }\n }\n\n // Calculate overall status\n const completedCount = stepResults.filter((r) => r.status === 'completed').length;\n const failedCount = stepResults.filter((r) => r.status === 'failed').length;\n const totalDuration = Date.now() - startTime;\n\n let status: RunPipelineOutput['status'];\n if (failedCount === 0) {\n status = 'completed';\n } else if (completedCount > 0) {\n status = 'partial';\n } else {\n status = 'failed';\n }\n\n // Build summary\n const summary = buildSummary(config, stepResults, totalDuration, totalTokens);\n\n // Emit pipeline complete event\n emitProgress(onProgress, {\n type: 'pipeline_complete',\n progress: {\n completed: executionOrder.length,\n total: executionOrder.length,\n percentage: 100,\n },\n message: summary,\n });\n\n return {\n status,\n totalDuration,\n totalTokens,\n steps: stepResults,\n files,\n summary,\n errors: errors.length > 0 ? errors : undefined,\n };\n}\n\n/**\n * Build execution order respecting dependencies (topological sort)\n */\nfunction buildExecutionOrder(steps: PipelineStep[]): PipelineStep[] {\n const result: PipelineStep[] = [];\n const visited = new Set<string>();\n const stepMap = new Map(steps.map((s) => [s.id, s]));\n\n function visit(stepId: string) {\n if (visited.has(stepId)) return;\n visited.add(stepId);\n\n const step = stepMap.get(stepId);\n if (!step) return;\n\n // Visit dependencies first\n if (step.dependsOn) {\n for (const depId of step.dependsOn) {\n visit(depId);\n }\n }\n\n result.push(step);\n }\n\n for (const step of steps) {\n visit(step.id);\n }\n\n return result;\n}\n\n/**\n * Check if dependencies completed successfully\n */\nfunction checkDependencies(step: PipelineStep, stepResults: Record<string, PipelineStepResult>): string | null {\n if (!step.dependsOn) return null;\n\n for (const depId of step.dependsOn) {\n const depResult = stepResults[depId];\n if (!depResult || depResult.status === 'failed') {\n return depId;\n }\n }\n\n return null;\n}\n\n/**\n * Execute a single pipeline step\n */\nasync function executeStep(\n step: PipelineStep,\n context: PipelineContext,\n validation: ValidationResult,\n defaultArgs?: Record<string, unknown>,\n additionalArgs?: Record<string, unknown>\n): Promise<PipelineStepResult> {\n const handler = toolHandlers[step.tool];\n if (!handler) {\n throw new Error(`Unknown tool: ${step.tool}`);\n }\n\n // Build arguments\n const args: Record<string, unknown> = {\n ...defaultArgs,\n ...step.args,\n ...additionalArgs,\n projectRoot: context.projectRoot,\n };\n\n // Resolve argument references to previous step outputs\n resolveArgReferences(args, context);\n\n // Execute the tool\n const result = await handler(args, validation);\n\n // Parse the result\n const content = result.content?.[0];\n const text = content?.type === 'text' ? content.text : '';\n const tokensUsed = result.tokensUsed ?? 0;\n\n // Extract file paths from output (look for \"Saved to:\" pattern)\n const files: string[] = [];\n const savedMatch = text.match(/Saved to:\\s*`?([^\\s`]+)`?/g);\n if (savedMatch) {\n for (const match of savedMatch) {\n const path = match.replace(/Saved to:\\s*`?/, '').replace(/`$/, '');\n files.push(path);\n }\n }\n\n return {\n stepId: step.id,\n status: 'completed',\n duration: 0, // Will be set by caller\n tokensUsed,\n output: text.substring(0, 2000), // Truncate for summary\n files,\n };\n}\n\n/**\n * Resolve argument references like ${stepId.output}\n */\nfunction resolveArgReferences(args: Record<string, unknown>, context: PipelineContext): void {\n for (const [key, value] of Object.entries(args)) {\n if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {\n const ref = value.slice(2, -1);\n const [stepId, field] = ref.split('.');\n\n if (stepId && field) {\n const stepResult = context.stepResults[stepId];\n if (stepResult && field === 'output') {\n args[key] = stepResult.output;\n } else if (context.sharedData[ref]) {\n args[key] = context.sharedData[ref];\n }\n }\n }\n }\n}\n\n/**\n * Emit a progress event if callback is provided\n */\nfunction emitProgress(callback: PipelineProgressCallback | undefined, event: PipelineProgressEvent): void {\n if (callback) {\n callback(event);\n }\n}\n\n/**\n * Build a summary message for the pipeline execution\n */\nfunction buildSummary(\n config: PipelineConfig,\n results: PipelineStepResult[],\n duration: number,\n tokens: number\n): string {\n const completed = results.filter((r) => r.status === 'completed').length;\n const failed = results.filter((r) => r.status === 'failed').length;\n const skipped = results.filter((r) => r.status === 'skipped').length;\n\n const durationSec = (duration / 1000).toFixed(1);\n\n let summary = `## Pipeline: ${config.name}\\n\\n`;\n summary += `**Status:** ${failed === 0 ? '✅ Complete' : `⚠️ ${failed} failed`}\\n`;\n summary += `**Duration:** ${durationSec}s\\n`;\n summary += `**Tokens Used:** ${tokens.toLocaleString()}\\n\\n`;\n summary += `### Steps\\n`;\n summary += `- ✅ Completed: ${completed}\\n`;\n if (failed > 0) summary += `- ❌ Failed: ${failed}\\n`;\n if (skipped > 0) summary += `- ⏭️ Skipped: ${skipped}\\n`;\n\n return summary;\n}\n\n/**\n * Calculate hash for input file (for incremental mode)\n */\nexport function hashFile(filePath: string): string | null {\n try {\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath);\n return createHash('sha256').update(content).digest('hex').substring(0, 16);\n } catch {\n return null;\n }\n}\n\n/**\n * Load input files and calculate hashes\n */\nexport function getInputHashes(projectRoot: string, patterns: string[]): Record<string, string> {\n const hashes: Record<string, string> = {};\n\n for (const pattern of patterns) {\n const fullPath = resolve(projectRoot, pattern);\n const hash = hashFile(fullPath);\n if (hash) {\n hashes[pattern] = hash;\n }\n }\n\n return hashes;\n}\n","/**\n * Run Pipeline Tool\n *\n * Orchestrates the execution of VasperaPM tool pipelines for automated\n * document generation and backlog creation.\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolDefinition } from '../types.js';\nimport { markdownResult, errorResult } from '../types.js';\nimport type { ValidationResult } from '../../middleware/auth.js';\nimport { resolve } from 'path';\nimport type {\n PipelineType,\n RunPipelineInput,\n PipelineConfig,\n PipelineContext,\n PipelineProgressEvent,\n} from './types.js';\nimport { PIPELINE_CONFIGS } from './types.js';\nimport { executePipeline } from './executor.js';\n\n// Re-export types for external use\nexport * from './types.js';\nexport { executePipeline } from './executor.js';\n\n/**\n * run_pipeline tool - Orchestrate VasperaPM tool pipelines\n */\nexport const runPipelineTool: ToolDefinition = {\n tool: {\n name: 'run_pipeline',\n description: `Execute a VasperaPM pipeline to automatically generate documentation and backlog items.\n\nAvailable pipelines:\n- **docs-first**: Start with PRD → Architecture → Tests → Backlog → Export\n- **code-first**: Analyze code → Infer PRD → User Flows → Tech Debt\n- **full**: Complete analysis combining both pipelines\n- **custom**: Define your own pipeline steps\n\nThe pipeline orchestrates multiple VasperaPM tools, respects dependencies between steps,\nand generates a comprehensive set of deliverables.\n\nBest for: One-click generation of all project documentation and backlog items.`,\n inputSchema: {\n type: 'object',\n properties: {\n pipeline: {\n type: 'string',\n enum: ['docs-first', 'code-first', 'full', 'custom'],\n default: 'full',\n description: 'Pipeline type to execute',\n },\n projectRoot: {\n type: 'string',\n description: 'Project root path (defaults to current directory)',\n },\n repoPath: {\n type: 'string',\n description: 'Path to code repository (for code-first and full pipelines)',\n },\n prd: {\n type: 'string',\n description: 'PRD content (for docs-first pipeline)',\n },\n code: {\n type: 'string',\n description: 'Code content to analyze (for code-first pipeline, alternative to repoPath)',\n },\n techStack: {\n type: 'string',\n description: 'Technology stack description (helps with analysis)',\n },\n platform: {\n type: 'string',\n enum: ['jira', 'ado', 'linear', 'github'],\n default: 'ado',\n description: 'Target platform for backlog export',\n },\n projectKey: {\n type: 'string',\n description: 'Project key for tracker integration (e.g., \"PROJ\")',\n },\n incremental: {\n type: 'boolean',\n default: false,\n description: 'Skip steps if inputs unchanged (experimental)',\n },\n customSteps: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n tool: { type: 'string' },\n args: { type: 'object' },\n dependsOn: { type: 'array', items: { type: 'string' } },\n },\n required: ['id', 'name', 'tool'],\n },\n description: 'Custom pipeline steps (for custom pipeline type)',\n },\n },\n required: [],\n },\n } as Tool,\n\n handler: async (args: Record<string, unknown>, validation: ValidationResult) => {\n const pipelineType = (args.pipeline as PipelineType) || 'full';\n const projectRoot = resolve((args.projectRoot as string) || process.cwd());\n const repoPath = args.repoPath as string | undefined;\n const prd = args.prd as string | undefined;\n const code = args.code as string | undefined;\n const techStack = args.techStack as string | undefined;\n const platform = (args.platform as string) || 'ado';\n const projectKey = args.projectKey as string | undefined;\n const incremental = args.incremental as boolean | undefined;\n\n // Validate pipeline type\n if (pipelineType === 'custom') {\n const customSteps = args.customSteps;\n if (!customSteps || !Array.isArray(customSteps) || customSteps.length === 0) {\n return errorResult('Custom pipeline requires customSteps array');\n }\n }\n\n // Get or build pipeline config\n let config: PipelineConfig;\n if (pipelineType === 'custom') {\n config = {\n id: 'custom',\n name: 'Custom Pipeline',\n description: 'User-defined pipeline',\n type: 'custom',\n steps: args.customSteps as PipelineConfig['steps'],\n };\n } else {\n config = PIPELINE_CONFIGS[pipelineType];\n }\n\n // Build execution context\n const context: PipelineContext = {\n projectRoot,\n stepResults: {},\n sharedData: {},\n };\n\n // Add shared data based on inputs\n if (prd) {\n context.sharedData['prd'] = prd;\n }\n if (code) {\n context.sharedData['code'] = code;\n }\n if (repoPath) {\n context.sharedData['repoPath'] = repoPath;\n }\n if (techStack) {\n context.sharedData['techStack'] = techStack;\n }\n\n // Build additional args to pass to all steps\n const additionalArgs: Record<string, unknown> = {};\n if (prd) additionalArgs['prd'] = prd;\n if (prd) additionalArgs['requirements'] = prd;\n if (code) additionalArgs['code'] = code;\n if (repoPath) additionalArgs['repoPath'] = repoPath;\n if (techStack) additionalArgs['techStack'] = techStack;\n if (platform) additionalArgs['platform'] = platform;\n if (projectKey) additionalArgs['projectKey'] = projectKey;\n\n // Collect progress messages for output\n const progressMessages: string[] = [];\n const onProgress = (event: PipelineProgressEvent) => {\n const emoji = getProgressEmoji(event.type);\n progressMessages.push(`${emoji} ${event.message}`);\n };\n\n try {\n // Execute the pipeline\n const result = await executePipeline(config, context, validation, onProgress, {\n incremental,\n additionalArgs,\n });\n\n // Build output markdown\n let output = `# ${config.name} Results\\n\\n`;\n output += `${result.summary}\\n\\n`;\n\n output += `### Progress Log\\n\\n`;\n output += progressMessages.map((m) => `- ${m}`).join('\\n');\n output += '\\n\\n';\n\n if (result.files.length > 0) {\n output += `### Generated Files\\n\\n`;\n output += result.files.map((f) => `- \\`${f}\\``).join('\\n');\n output += '\\n\\n';\n }\n\n if (result.errors && result.errors.length > 0) {\n output += `### Errors\\n\\n`;\n output += result.errors.map((e) => `- ❌ ${e}`).join('\\n');\n output += '\\n\\n';\n }\n\n output += `---\\n`;\n output += `*Pipeline completed in ${(result.totalDuration / 1000).toFixed(1)}s using ${result.totalTokens.toLocaleString()} tokens*`;\n\n return markdownResult(output, result.totalTokens);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return errorResult(`Pipeline execution failed: ${message}`);\n }\n },\n\n requiredScope: 'tools:run_pipeline',\n};\n\n/**\n * Get emoji for progress event type\n */\nfunction getProgressEmoji(type: PipelineProgressEvent['type']): string {\n switch (type) {\n case 'step_start':\n return '🔄';\n case 'step_complete':\n return '✅';\n case 'step_failed':\n return '❌';\n case 'step_skipped':\n return '⏭️';\n case 'pipeline_complete':\n return '🎉';\n default:\n return '•';\n }\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolHandler, ToolDefinition } from './types.js';\n\n// Plugin loader for runtime validation and dynamic discovery\nexport { loadTools, getLoadedToolNames, validateRequiredTools } from './plugin-loader.js';\n\n// Import all tool definitions (static imports for TypeScript build safety)\nimport { explodeBacklogTool } from './explode-backlog.js';\nimport { inferPrdTool } from './infer-prd.js';\nimport { synthesizePrdTool } from './synthesize-prd.js';\nimport { generateArchitectureTool } from './generate-architecture.js';\nimport { handoffPackageTool } from './handoff-package.js';\nimport { synthesizeRequirementsTool } from './synthesize-requirements.js';\nimport { reviewPrdTool } from './review-prd.js';\nimport { syncToTrackerTool } from './sync-to-tracker.js';\nimport { reverseEngineerFlowsTool } from './reverse-engineer-flows.js';\nimport { reverseEngineerFrontendTool } from './reverse-engineer-frontend.js';\nimport { generateTestSpecsTool } from './generate-test-specs.js';\nimport { explainCodebaseTool } from './explain-codebase.js';\nimport { validateImplementationTool } from './validate-implementation.js';\nimport { suggestRefactorsTool } from './suggest-refactors.js';\nimport { generateApiDocsTool } from './generate-api-docs.js';\nimport { dependencyAuditTool } from './dependency-audit.js';\nimport { estimateMigrationTool } from './estimate-migration.js';\n// Phase 7: Powerhouse tools\nimport { verifyDocsCodeTool } from './verify-docs-code.js';\nimport { runBenchmarkTool } from './run-benchmark.js';\nimport { analyzeGitFreshnessTool } from './analyze-git-freshness.js';\n// Phase 8: Consolidation tools\nimport { exportRequirementsTool } from './export-requirements.js';\nimport { generateCompleteBacklogTool } from './generate-complete-backlog.js';\n// Phase 9: DevOps tools\nimport { generateDeploymentRunbookTool } from './generate-deployment-runbook.js';\n// Phase 10: Traceability tools\nimport { generateChangelogTool } from './generate-changelog.js';\nimport { detectRegressionsTool } from './detect-regressions.js';\nimport { generateSprintReportTool } from './generate-sprint-report.js';\nimport { trackEstimatesTool } from './track-estimates.js';\nimport { getAuditTrailTool } from './get-audit-trail.js';\n// Phase 11: Pipeline Automation\nimport { runPipelineTool } from './run-pipeline/index.js';\n\n// Register all tools\nconst toolDefinitions: ToolDefinition[] = [\n // Phase 3: Initial tools\n explodeBacklogTool,\n inferPrdTool,\n synthesizePrdTool,\n generateArchitectureTool,\n handoffPackageTool,\n // Phase 4: Additional PM tools\n synthesizeRequirementsTool,\n reviewPrdTool,\n syncToTrackerTool,\n // Phase 5: Code-first tools\n reverseEngineerFlowsTool,\n reverseEngineerFrontendTool,\n generateTestSpecsTool,\n explainCodebaseTool,\n validateImplementationTool,\n suggestRefactorsTool,\n // Phase 6: Advanced tools\n generateApiDocsTool,\n dependencyAuditTool,\n estimateMigrationTool,\n // Phase 7: Powerhouse tools\n verifyDocsCodeTool,\n runBenchmarkTool,\n analyzeGitFreshnessTool,\n // Phase 8: Consolidation tools\n exportRequirementsTool,\n generateCompleteBacklogTool,\n // Phase 9: DevOps tools\n generateDeploymentRunbookTool,\n // Phase 10: Traceability tools\n generateChangelogTool,\n detectRegressionsTool,\n generateSprintReportTool,\n trackEstimatesTool,\n getAuditTrailTool,\n // Phase 11: Pipeline Automation\n runPipelineTool,\n];\n\n// Export tools array for MCP server\nexport const tools: Tool[] = toolDefinitions.map((t) => t.tool);\n\n// Export handlers map for MCP server\nexport const toolHandlers: Record<string, ToolHandler> = Object.fromEntries(\n toolDefinitions.map((t) => [t.tool.name, t.handler])\n);\n\n// Export individual tools for testing\nexport {\n explodeBacklogTool,\n inferPrdTool,\n synthesizePrdTool,\n generateArchitectureTool,\n handoffPackageTool,\n synthesizeRequirementsTool,\n reviewPrdTool,\n syncToTrackerTool,\n reverseEngineerFlowsTool,\n reverseEngineerFrontendTool,\n generateTestSpecsTool,\n explainCodebaseTool,\n validateImplementationTool,\n suggestRefactorsTool,\n generateApiDocsTool,\n dependencyAuditTool,\n estimateMigrationTool,\n // Phase 7: Powerhouse tools\n verifyDocsCodeTool,\n runBenchmarkTool,\n analyzeGitFreshnessTool,\n // Phase 8: Consolidation tools\n exportRequirementsTool,\n generateCompleteBacklogTool,\n // Phase 9: DevOps tools\n generateDeploymentRunbookTool,\n // Phase 10: Traceability tools\n generateChangelogTool,\n detectRegressionsTool,\n generateSprintReportTool,\n trackEstimatesTool,\n getAuditTrailTool,\n // Phase 11: Pipeline Automation\n runPipelineTool,\n};\n\n// Export types\nexport type { ToolHandler, ToolDefinition, ToolResult } from './types.js';\nexport { textResult, jsonResult, errorResult, markdownResult } from './types.js';\n\n/**\n * Validate all registered tools have required properties\n * Call at server startup to catch configuration errors early\n */\nexport function validateToolsAtStartup(): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n for (const def of toolDefinitions) {\n const toolName = def.tool?.name || 'unknown';\n\n // Validate tool object\n if (!def.tool) {\n errors.push(`${toolName}: Missing 'tool' property`);\n continue;\n }\n\n if (!def.tool.name || typeof def.tool.name !== 'string') {\n errors.push(`${toolName}: Missing or invalid 'tool.name'`);\n }\n\n if (!def.tool.description || typeof def.tool.description !== 'string') {\n errors.push(`${toolName}: Missing or invalid 'tool.description'`);\n }\n\n if (!def.tool.inputSchema || typeof def.tool.inputSchema !== 'object') {\n errors.push(`${toolName}: Missing or invalid 'tool.inputSchema'`);\n }\n\n // Validate handler\n if (!def.handler || typeof def.handler !== 'function') {\n errors.push(`${toolName}: Missing or invalid 'handler' function`);\n }\n }\n\n if (errors.length > 0) {\n console.error('[Tools] Validation errors:', errors);\n } else {\n console.log(`[Tools] All ${toolDefinitions.length} tools validated successfully`);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Get tool statistics for logging\n */\nexport function getToolStats(): { count: number; names: string[] } {\n return {\n count: toolDefinitions.length,\n names: toolDefinitions.map((t) => t.tool.name),\n };\n}\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ErrorCode,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { validateApiKey } from './middleware/auth.js';\nimport { trackUsage } from './middleware/usage.js';\nimport { checkRateLimit } from './middleware/rate-limit.js';\nimport { tools, toolHandlers, validateToolsAtStartup, getToolStats } from './tools/index.js';\n\nconst VERSION = '0.1.2';\n\n// Startup validation - validate all tools at initialization\nconst stats = getToolStats();\nconsole.error(`[VasperaPM] Server initializing with ${stats.count} tools registered`);\n\nconst validation = validateToolsAtStartup();\nif (!validation.valid) {\n console.error('[VasperaPM] CRITICAL: Tool validation failed!');\n console.error('[VasperaPM] Errors:', validation.errors.join(', '));\n process.exit(1);\n}\n\nconst server = new Server(\n {\n name: 'vaspera-pm',\n version: VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// List available tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n // Debug logging to diagnose tool availability issues\n console.error(`[VasperaPM] ListTools called - returning ${tools.length} tools`);\n if (tools.length === 0) {\n console.error('[VasperaPM] WARNING: Tools array is empty!');\n } else {\n console.error(`[VasperaPM] Available tools: ${tools.map(t => t.name).join(', ')}`);\n }\n return { tools };\n});\n\n// Handle tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n // Extract API key from environment or args\n const apiKey = process.env.VASPERA_API_KEY || (args as Record<string, unknown>)?._apiKey as string | undefined;\n\n // Validate API key\n const validation = await validateApiKey(apiKey);\n if (!validation.valid) {\n return {\n content: [{ type: 'text', text: `Authentication failed: ${validation.error?.message || 'Invalid API key'}` }],\n isError: true,\n };\n }\n\n // Check rate limit\n const rateCheck = await checkRateLimit(validation.userId!, validation.tier!);\n if (!rateCheck.allowed) {\n return {\n content: [{ type: 'text', text: `Rate limit exceeded. ${rateCheck.remaining} calls remaining. Resets at ${rateCheck.resetsAt?.toISOString()}` }],\n isError: true,\n };\n }\n\n // Check quota\n if (validation.quota && validation.quota.remaining <= 0) {\n return {\n content: [{ type: 'text', text: `Monthly quota exceeded. Upgrade your plan for more API calls.` }],\n isError: true,\n };\n }\n\n // Execute tool\n const startTime = Date.now();\n let result;\n let success = true;\n let errorCode: string | undefined;\n let tokensUsed = 0;\n\n try {\n const handler = toolHandlers[name];\n if (!handler) {\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);\n }\n\n // Remove internal _apiKey from args before passing to handler\n const cleanArgs = { ...args as Record<string, unknown> };\n delete cleanArgs._apiKey;\n\n const toolResult = await handler(cleanArgs, validation);\n result = toolResult.content;\n tokensUsed = toolResult.tokensUsed || 0;\n } catch (error) {\n success = false;\n errorCode = error instanceof McpError ? error.code.toString() : 'TOOL_ERROR';\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n result = [{ type: 'text' as const, text: `Error: ${errorMessage}` }];\n }\n\n const latencyMs = Date.now() - startTime;\n\n // Track usage asynchronously\n trackUsage({\n userId: validation.userId!,\n apiKeyId: validation.apiKeyId!,\n toolName: name,\n tokensUsed,\n latencyMs,\n success,\n errorCode,\n metadata: { args: sanitizeArgs(args as Record<string, unknown>) },\n }).catch((err) => {\n console.error('Failed to track usage:', err);\n });\n\n return {\n content: result,\n isError: !success,\n };\n});\n\n// Sanitize args for logging (remove sensitive data)\nfunction sanitizeArgs(args: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!args) return {};\n\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(args)) {\n if (key.toLowerCase().includes('key') || key.toLowerCase().includes('secret') || key.toLowerCase().includes('token')) {\n sanitized[key] = '[REDACTED]';\n } else if (typeof value === 'string' && value.length > 500) {\n sanitized[key] = value.substring(0, 500) + '...[truncated]';\n } else {\n sanitized[key] = value;\n }\n }\n return sanitized;\n}\n\n// Start server (exported for CLI)\nexport async function startServer(): Promise<void> {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`VasperaPM MCP Server v${VERSION} running`);\n}\n\n// Allow direct execution\nif (import.meta.url === `file://${process.argv[1]}`) {\n startServer().catch((error) => {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n });\n}\n","/**\n * VasperaPM Discovery Engine\n *\n * Auto-discovers documentation and code files in a project.\n * Categorizes and organizes sources for analysis.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join, extname, relative, basename } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DocCategory =\n | 'readme'\n | 'prd'\n | 'api'\n | 'architecture'\n | 'changelog'\n | 'contributing'\n | 'other';\n\nexport type CodeCategory =\n | 'routes'\n | 'components'\n | 'utils'\n | 'types'\n | 'tests'\n | 'config'\n | 'other';\n\nexport interface DiscoveredDoc {\n path: string;\n relativePath: string;\n category: DocCategory;\n filename: string;\n size: number;\n content?: string;\n}\n\nexport interface DiscoveredCode {\n path: string;\n relativePath: string;\n category: CodeCategory;\n filename: string;\n language: string;\n size: number;\n content?: string;\n}\n\nexport interface DiscoveryResult {\n projectRoot: string;\n docs: DiscoveredDoc[];\n code: DiscoveredCode[];\n summary: {\n totalDocs: number;\n totalCode: number;\n docsByCategory: Record<DocCategory, number>;\n codeByLanguage: Record<string, number>;\n };\n}\n\nexport interface DiscoveryOptions {\n /** Include file contents (increases memory usage) */\n includeContent?: boolean;\n /** Maximum file size to read (bytes) */\n maxFileSize?: number;\n /** Additional paths to exclude */\n excludePaths?: string[];\n /** Maximum depth to traverse */\n maxDepth?: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_OPTIONS: Required<DiscoveryOptions> = {\n includeContent: false,\n maxFileSize: 1024 * 1024, // 1MB\n excludePaths: [],\n maxDepth: 10,\n};\n\n// Paths to always exclude\nconst EXCLUDE_PATHS = [\n 'node_modules',\n '.git',\n '.next',\n '.vercel',\n 'dist',\n 'build',\n 'coverage',\n '.turbo',\n '.cache',\n '__pycache__',\n 'venv',\n '.venv',\n 'vendor',\n 'target',\n '.idea',\n '.vscode',\n];\n\n// Documentation file patterns\nconst DOC_PATTERNS: Record<DocCategory, RegExp[]> = {\n readme: [/^readme/i, /^about/i],\n prd: [/^prd/i, /^spec/i, /^requirements/i, /^features/i],\n api: [/^api/i, /^openapi/i, /^swagger/i, /^endpoints/i],\n architecture: [/^architecture/i, /^design/i, /^adr/i, /^decisions/i, /^tech/i],\n changelog: [/^changelog/i, /^history/i, /^releases/i, /^version/i],\n contributing: [/^contributing/i, /^develop/i, /^setup/i],\n other: [],\n};\n\n// Documentation directories to search\nconst DOC_DIRECTORIES = [\n 'docs',\n 'doc',\n 'documentation',\n 'specifications',\n 'spec',\n 'specs',\n 'requirements',\n 'design',\n 'architecture',\n 'adr',\n 'decisions',\n];\n\n// Code file extensions by language\nconst CODE_EXTENSIONS: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.py': 'python',\n '.go': 'go',\n '.java': 'java',\n '.rs': 'rust',\n '.rb': 'ruby',\n '.php': 'php',\n '.cs': 'csharp',\n '.swift': 'swift',\n '.kt': 'kotlin',\n};\n\n// Code category patterns\nconst CODE_PATTERNS: Record<CodeCategory, RegExp[]> = {\n routes: [/routes?/i, /api/i, /endpoints?/i, /handlers?/i, /controllers?/i],\n components: [/components?/i, /views?/i, /pages?/i, /screens?/i, /ui/i],\n utils: [/utils?/i, /helpers?/i, /lib/i, /shared/i, /common/i],\n types: [/types?/i, /interfaces?/i, /models?/i, /schemas?/i, /dtos?/i],\n tests: [/tests?/i, /__tests__/i, /spec/i, /\\.test\\./i, /\\.spec\\./i],\n config: [/config/i, /settings?/i, /env/i],\n other: [],\n};\n\n// ============================================================================\n// Discovery Functions\n// ============================================================================\n\n/**\n * Discover all documentation and code files in a project\n */\nexport async function discoverProject(\n projectRoot: string,\n options: DiscoveryOptions = {}\n): Promise<DiscoveryResult> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const excludePaths = [...EXCLUDE_PATHS, ...opts.excludePaths];\n\n const docs: DiscoveredDoc[] = [];\n const code: DiscoveredCode[] = [];\n\n // Discover documentation\n await discoverDocs(projectRoot, projectRoot, docs, excludePaths, opts, 0);\n\n // Discover code\n await discoverCode(projectRoot, projectRoot, code, excludePaths, opts, 0);\n\n // Build summary\n const docsByCategory: Record<DocCategory, number> = {\n readme: 0,\n prd: 0,\n api: 0,\n architecture: 0,\n changelog: 0,\n contributing: 0,\n other: 0,\n };\n\n const codeByLanguage: Record<string, number> = {};\n\n for (const doc of docs) {\n docsByCategory[doc.category]++;\n }\n\n for (const file of code) {\n codeByLanguage[file.language] = (codeByLanguage[file.language] || 0) + 1;\n }\n\n return {\n projectRoot,\n docs,\n code,\n summary: {\n totalDocs: docs.length,\n totalCode: code.length,\n docsByCategory,\n codeByLanguage,\n },\n };\n}\n\n/**\n * Recursively discover documentation files\n */\nasync function discoverDocs(\n currentPath: string,\n projectRoot: string,\n docs: DiscoveredDoc[],\n excludePaths: string[],\n options: Required<DiscoveryOptions>,\n depth: number\n): Promise<void> {\n if (depth > options.maxDepth) return;\n if (!existsSync(currentPath)) return;\n\n const stat = statSync(currentPath);\n if (!stat.isDirectory()) return;\n\n const entries = readdirSync(currentPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relativePath = relative(projectRoot, fullPath);\n\n // Skip excluded paths\n if (excludePaths.some((ex) => relativePath.includes(ex))) continue;\n\n if (entry.isDirectory()) {\n // Recurse into documentation directories\n const isDirDoc = DOC_DIRECTORIES.some(\n (d) => entry.name.toLowerCase() === d.toLowerCase()\n );\n\n if (isDirDoc || depth === 0) {\n await discoverDocs(fullPath, projectRoot, docs, excludePaths, options, depth + 1);\n }\n } else if (entry.isFile()) {\n // Check if it's a documentation file\n const ext = extname(entry.name).toLowerCase();\n if (ext === '.md' || ext === '.mdx' || ext === '.txt' || ext === '.rst') {\n const doc = createDocEntry(fullPath, projectRoot, options);\n if (doc) docs.push(doc);\n }\n\n // Also check for YAML/JSON specs at root level\n if (depth <= 1 && (ext === '.yaml' || ext === '.yml' || ext === '.json')) {\n const name = entry.name.toLowerCase();\n if (name.includes('openapi') || name.includes('swagger') || name.includes('api')) {\n const doc = createDocEntry(fullPath, projectRoot, options, 'api');\n if (doc) docs.push(doc);\n }\n }\n }\n }\n}\n\n/**\n * Recursively discover code files\n */\nasync function discoverCode(\n currentPath: string,\n projectRoot: string,\n code: DiscoveredCode[],\n excludePaths: string[],\n options: Required<DiscoveryOptions>,\n depth: number\n): Promise<void> {\n if (depth > options.maxDepth) return;\n if (!existsSync(currentPath)) return;\n\n const stat = statSync(currentPath);\n if (!stat.isDirectory()) return;\n\n const entries = readdirSync(currentPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentPath, entry.name);\n const relativePath = relative(projectRoot, fullPath);\n\n // Skip excluded paths\n if (excludePaths.some((ex) => relativePath.includes(ex))) continue;\n\n if (entry.isDirectory()) {\n // Skip hidden directories (except .github)\n if (entry.name.startsWith('.') && entry.name !== '.github') continue;\n\n await discoverCode(fullPath, projectRoot, code, excludePaths, options, depth + 1);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n const language = CODE_EXTENSIONS[ext];\n\n if (language) {\n const codeFile = createCodeEntry(fullPath, projectRoot, language, options);\n if (codeFile) code.push(codeFile);\n }\n }\n }\n}\n\n/**\n * Create a documentation entry\n */\nfunction createDocEntry(\n fullPath: string,\n projectRoot: string,\n options: Required<DiscoveryOptions>,\n forceCategory?: DocCategory\n): DiscoveredDoc | null {\n try {\n const stat = statSync(fullPath);\n if (stat.size > options.maxFileSize) return null;\n\n const relativePath = relative(projectRoot, fullPath);\n const filename = basename(fullPath);\n const category = forceCategory || categorizeDoc(filename, relativePath);\n\n const doc: DiscoveredDoc = {\n path: fullPath,\n relativePath,\n category,\n filename,\n size: stat.size,\n };\n\n if (options.includeContent) {\n doc.content = readFileSync(fullPath, 'utf-8');\n }\n\n return doc;\n } catch {\n return null;\n }\n}\n\n/**\n * Create a code entry\n */\nfunction createCodeEntry(\n fullPath: string,\n projectRoot: string,\n language: string,\n options: Required<DiscoveryOptions>\n): DiscoveredCode | null {\n try {\n const stat = statSync(fullPath);\n if (stat.size > options.maxFileSize) return null;\n\n const relativePath = relative(projectRoot, fullPath);\n const filename = basename(fullPath);\n const category = categorizeCode(relativePath, filename);\n\n const codeFile: DiscoveredCode = {\n path: fullPath,\n relativePath,\n category,\n filename,\n language,\n size: stat.size,\n };\n\n if (options.includeContent) {\n codeFile.content = readFileSync(fullPath, 'utf-8');\n }\n\n return codeFile;\n } catch {\n return null;\n }\n}\n\n/**\n * Categorize a documentation file\n */\nfunction categorizeDoc(filename: string, relativePath: string): DocCategory {\n const lower = filename.toLowerCase();\n const pathLower = relativePath.toLowerCase();\n\n for (const [category, patterns] of Object.entries(DOC_PATTERNS)) {\n if (category === 'other') continue;\n for (const pattern of patterns) {\n if (pattern.test(lower) || pattern.test(pathLower)) {\n return category as DocCategory;\n }\n }\n }\n\n return 'other';\n}\n\n/**\n * Categorize a code file\n */\nfunction categorizeCode(relativePath: string, filename: string): CodeCategory {\n const pathLower = relativePath.toLowerCase();\n const nameLower = filename.toLowerCase();\n\n for (const [category, patterns] of Object.entries(CODE_PATTERNS)) {\n if (category === 'other') continue;\n for (const pattern of patterns) {\n if (pattern.test(pathLower) || pattern.test(nameLower)) {\n return category as CodeCategory;\n }\n }\n }\n\n return 'other';\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Read file content with size limit\n */\nexport function readFileContent(\n filePath: string,\n maxSize: number = 1024 * 1024\n): string | null {\n try {\n const stat = statSync(filePath);\n if (stat.size > maxSize) return null;\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Get a summary string for display\n */\nexport function formatDiscoverySummary(result: DiscoveryResult): string {\n const lines = [\n `📚 Discovered ${result.summary.totalDocs} documentation files`,\n `📁 Discovered ${result.summary.totalCode} code files`,\n '',\n 'Documentation by category:',\n ];\n\n for (const [category, count] of Object.entries(result.summary.docsByCategory)) {\n if (count > 0) {\n lines.push(` • ${category}: ${count}`);\n }\n }\n\n lines.push('', 'Code by language:');\n for (const [language, count] of Object.entries(result.summary.codeByLanguage)) {\n lines.push(` • ${language}: ${count}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Filter to get only important code files (routes, types, main logic)\n */\nexport function getImportantCodeFiles(result: DiscoveryResult): DiscoveredCode[] {\n const important: DiscoveredCode[] = [];\n\n // Prioritize routes, types, and utils\n const priorityCategories: CodeCategory[] = ['routes', 'types', 'utils'];\n\n for (const category of priorityCategories) {\n important.push(...result.code.filter((c) => c.category === category));\n }\n\n // Add some components if we don't have many files yet\n if (important.length < 20) {\n const components = result.code.filter((c) => c.category === 'components');\n important.push(...components.slice(0, 20 - important.length));\n }\n\n return important;\n}\n\n/**\n * Get all documentation content concatenated (for AI analysis)\n */\nexport function getAllDocsContent(\n docs: DiscoveredDoc[],\n maxTotalSize: number = 100000\n): string {\n let totalSize = 0;\n const contents: string[] = [];\n\n // Sort by category importance\n const sortOrder: DocCategory[] = ['readme', 'prd', 'api', 'architecture', 'other', 'changelog', 'contributing'];\n const sorted = [...docs].sort((a, b) => {\n return sortOrder.indexOf(a.category) - sortOrder.indexOf(b.category);\n });\n\n for (const doc of sorted) {\n if (totalSize >= maxTotalSize) break;\n\n const content = doc.content || readFileContent(doc.path);\n if (!content) continue;\n\n const header = `\\n\\n---\\n## File: ${doc.relativePath}\\n---\\n\\n`;\n const toAdd = header + content;\n\n if (totalSize + toAdd.length <= maxTotalSize) {\n contents.push(toAdd);\n totalSize += toAdd.length;\n }\n }\n\n return contents.join('');\n}\n\n/**\n * Get important code content concatenated (for AI analysis)\n */\nexport function getCodeContent(\n code: DiscoveredCode[],\n maxTotalSize: number = 100000\n): string {\n let totalSize = 0;\n const contents: string[] = [];\n\n // Filter to important files\n const important = code.filter((c) =>\n ['routes', 'types', 'utils', 'components'].includes(c.category)\n );\n\n for (const file of important) {\n if (totalSize >= maxTotalSize) break;\n\n const content = file.content || readFileContent(file.path);\n if (!content) continue;\n\n const header = `\\n\\n---\\n## File: ${file.relativePath} (${file.language})\\n---\\n\\n`;\n const toAdd = header + content;\n\n if (totalSize + toAdd.length <= maxTotalSize) {\n contents.push(toAdd);\n totalSize += toAdd.length;\n }\n }\n\n return contents.join('');\n}\n","/**\n * VasperaPM Verification Engine\n *\n * Cross-validates documentation against code implementation.\n * Detects drift, undocumented features, and unimplemented requirements.\n */\n\nimport { createCompletion, createJsonCompletion } from '../ai/client.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type VerificationStatus =\n | 'verified' // Docs and code match\n | 'drift' // Docs and code disagree\n | 'undocumented' // Found in code but not docs\n | 'unimplemented'; // Found in docs but not code\n\nexport type DriftSeverity = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface Requirement {\n id: string;\n description: string;\n category: 'feature' | 'api' | 'security' | 'performance' | 'ui' | 'data';\n source: 'docs' | 'code' | 'both';\n sourceFile?: string;\n sourceLine?: number;\n}\n\nexport interface VerifiedRequirement {\n requirement?: Requirement;\n // Allow flat structure from AI\n id?: string;\n description?: string;\n category?: string;\n status: VerificationStatus;\n confidence: number; // 0-100\n documentedBehavior?: string;\n implementedBehavior?: string;\n evidence?: {\n docReferences: string[];\n codeReferences: string[];\n };\n drift?: {\n severity: DriftSeverity;\n description: string;\n recommendation: 'update_docs' | 'update_code' | 'needs_discussion';\n };\n}\n\n// Helper to safely extract ID from a requirement\nfunction getReqId(req: VerifiedRequirement): string {\n return req.requirement?.id || req.id || 'UNKNOWN';\n}\n\n// Helper to safely extract description from a requirement\nfunction getReqDesc(req: VerifiedRequirement): string {\n return (\n req.requirement?.description ||\n req.description ||\n req.documentedBehavior ||\n req.implementedBehavior ||\n req.drift?.description ||\n 'No description available'\n );\n}\n\nexport interface VerificationResult {\n summary: {\n total: number;\n verified: number;\n drift: number;\n undocumented: number;\n unimplemented: number;\n overallConfidence: number;\n };\n requirements: VerifiedRequirement[];\n criticalDrift: VerifiedRequirement[];\n tokensUsed: {\n input: number;\n output: number;\n };\n}\n\nexport interface DriftReport {\n generatedAt: string;\n projectPath: string;\n summary: VerificationResult['summary'];\n critical: VerifiedRequirement[];\n high: VerifiedRequirement[];\n medium: VerifiedRequirement[];\n low: VerifiedRequirement[];\n undocumented: VerifiedRequirement[];\n unimplemented: VerifiedRequirement[];\n}\n\n// ============================================================================\n// Verification Engine\n// ============================================================================\n\n/**\n * Cross-validate documentation against code implementation\n */\nexport async function verify(\n docsContent: string,\n codeContent: string\n): Promise<VerificationResult> {\n // Step 1: Extract requirements from docs\n const docsRequirements = await extractRequirementsFromDocs(docsContent);\n\n // Step 2: Extract features from code\n const codeFeatures = await extractFeaturesFromCode(codeContent);\n\n // Step 3: Cross-validate\n const verified = await crossValidate(\n docsRequirements.requirements,\n codeFeatures.features,\n docsContent,\n codeContent\n );\n\n // Calculate summary\n const summary = {\n total: verified.requirements.length,\n verified: verified.requirements.filter((r) => r.status === 'verified').length,\n drift: verified.requirements.filter((r) => r.status === 'drift').length,\n undocumented: verified.requirements.filter((r) => r.status === 'undocumented').length,\n unimplemented: verified.requirements.filter((r) => r.status === 'unimplemented').length,\n overallConfidence: Math.round(\n verified.requirements.reduce((sum, r) => sum + r.confidence, 0) /\n verified.requirements.length\n ),\n };\n\n const criticalDrift = verified.requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity === 'critical'\n );\n\n return {\n summary,\n requirements: verified.requirements,\n criticalDrift,\n tokensUsed: {\n input:\n docsRequirements.tokensUsed.input +\n codeFeatures.tokensUsed.input +\n verified.tokensUsed.input,\n output:\n docsRequirements.tokensUsed.output +\n codeFeatures.tokensUsed.output +\n verified.tokensUsed.output,\n },\n };\n}\n\n/**\n * Extract requirements from documentation\n */\nasync function extractRequirementsFromDocs(docsContent: string): Promise<{\n requirements: Requirement[];\n tokensUsed: { input: number; output: number };\n}> {\n const systemPrompt = `You are a requirements extraction expert. Analyze documentation and extract all requirements.\n\nCRITICAL: Each requirement MUST have a detailed \"description\" field that fully explains what the requirement is. Enterprise developers will read these descriptions to understand what needs to be built.\n\nOutput format for each requirement:\n{\n \"id\": \"R-001\",\n \"description\": \"User authentication via email/password with JWT tokens - Users must be able to sign up and log in using email and password credentials. JWT tokens with configurable expiry for session management.\",\n \"category\": \"security\",\n \"sourceFile\": \"docs/PRD.md\",\n \"sourceLine\": 45\n}\n\nDescription guidelines:\n- Write 1-3 sentences that fully explain the requirement\n- Include specific details (limits, formats, behaviors)\n- Be concrete enough for a developer to implement\n- Include acceptance criteria when evident\n\nCategories: feature, api, security, performance, ui, data\n\nFocus on extracting:\n- Explicit requirements (\"must\", \"should\", \"will\")\n- API endpoints and behaviors\n- Security requirements (auth, permissions)\n- Performance requirements (limits, quotas)\n- UI/UX requirements\n- Data requirements (validation, formats)\n\nReturn a JSON object with a \"requirements\" array: {\"requirements\": [...]}`;\n\n const userMessage = `Extract all requirements from this documentation:\n\n${docsContent.substring(0, 80000)}`;\n\n const result = await createJsonCompletion<{ requirements: Requirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n // Handle case where AI returns array directly or wrapped object\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Ensure all requirements have source: 'docs'\n const requirements = reqs.map((r) => ({\n ...r,\n source: 'docs' as const,\n }));\n\n return {\n requirements,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n}\n\n/**\n * Extract features/capabilities from code\n */\nasync function extractFeaturesFromCode(codeContent: string): Promise<{\n features: Requirement[];\n tokensUsed: { input: number; output: number };\n}> {\n const systemPrompt = `You are a code analysis expert. Analyze code and extract all implemented features.\n\nCRITICAL: Each feature MUST have a detailed \"description\" field. Enterprise developers need to understand exactly what each feature does.\n\nOutput format for each feature:\n{\n \"id\": \"F-001\",\n \"description\": \"JWT-based authentication with 1-hour token expiry - Login endpoint at /api/auth/login accepts email/password, returns JWT access token and refresh token. Tokens stored in httpOnly cookies.\",\n \"category\": \"security\",\n \"sourceFile\": \"src/auth/login.ts\",\n \"sourceLine\": 12\n}\n\nDescription guidelines:\n- Write 1-3 sentences explaining WHAT the code does\n- Include concrete values (endpoints, limits, formats)\n- Be specific enough for documentation\n- Include actual implementation details found in code\n\nCategories: feature, api, security, performance, ui, data\n\nFocus on extracting:\n- API endpoints with their actual behaviors\n- Authentication/authorization implementations\n- Rate limiting, quotas, constraints (with actual values!)\n- Database operations and data models\n- Integration points (external services)\n- Data models and validation rules\n- Business logic and workflows\n- Error handling patterns\n\nReturn a JSON object with a \"requirements\" array: {\"requirements\": [...]}`;\n\n const userMessage = `Extract all implemented features from this code:\n\n${codeContent.substring(0, 80000)}`;\n\n const result = await createJsonCompletion<{ requirements: Requirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n // Handle case where AI returns array directly or wrapped object\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Ensure all features have source: 'code'\n const features = reqs.map((r) => ({\n ...r,\n source: 'code' as const,\n }));\n\n return {\n features,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n}\n\n/**\n * Cross-validate requirements against features\n */\nasync function crossValidate(\n docsRequirements: Requirement[],\n codeFeatures: Requirement[],\n docsContent: string,\n codeContent: string\n): Promise<{\n requirements: VerifiedRequirement[];\n tokensUsed: { input: number; output: number };\n}> {\n const systemPrompt = `You are a specification verification expert. Compare documentation requirements against code implementations.\n\nCRITICAL OUTPUT REQUIREMENT: For every item, you MUST include a human-readable \"description\" field that describes WHAT the requirement/feature is. Do NOT just return an ID - the description is ESSENTIAL for developer understanding.\n\nFor each item in your output, include these fields:\n{\n \"id\": \"R-001\",\n \"description\": \"COPY THE FULL DESCRIPTION FROM THE INPUT - User authentication via email/password with JWT tokens\",\n \"status\": \"verified|drift|undocumented|unimplemented\",\n \"confidence\": 85,\n \"documentedBehavior\": \"What the docs say this should do\",\n \"implementedBehavior\": \"What the code actually does\",\n \"evidence\": {\"docReferences\": [\"docs/PRD.md:45\"], \"codeReferences\": [\"src/auth/login.ts:12-45\"]},\n \"drift\": {\"severity\": \"high\", \"description\": \"What differs\", \"recommendation\": \"update_docs|update_code|needs_discussion\"}\n}\n\nStatus meanings:\n- VERIFIED: Docs and code match\n- DRIFT: Docs and code disagree (include severity: critical/high/medium/low)\n- UNDOCUMENTED: Feature exists in code but not in docs\n- UNIMPLEMENTED: Requirement in docs but not built\n\nSeverity guidelines:\n- CRITICAL: User-facing behavior differs (quotas, limits, pricing, security)\n- HIGH: API contracts differ (endpoints, parameters, responses)\n- MEDIUM: Internal implementation differs from spec\n- LOW: Documentation is incomplete but code is correct\n\nReturn: {\"requirements\": [...]}`;\n\n const docsReqJson = JSON.stringify(docsRequirements, null, 2);\n const codeFeatJson = JSON.stringify(codeFeatures, null, 2);\n\n const userMessage = `Cross-validate these documentation requirements against code features:\n\n## DOCUMENTATION REQUIREMENTS:\n${docsReqJson}\n\n## CODE FEATURES:\n${codeFeatJson}\n\n## SAMPLE DOCUMENTATION (for context):\n${docsContent.substring(0, 20000)}\n\n## SAMPLE CODE (for context):\n${codeContent.substring(0, 20000)}\n\nAnalyze each requirement and feature to determine verification status.`;\n\n const result = await createJsonCompletion<{ requirements: VerifiedRequirement[] }>({\n systemPrompt,\n userMessage,\n model: 'balanced',\n maxTokens: 16384,\n });\n\n // Handle case where AI returns array directly or wrapped object\n const reqs = Array.isArray(result.data) ? result.data : result.data.requirements || [];\n\n // Build lookup maps from original requirements and features for fallback descriptions\n const docsLookup = new Map<string, Requirement>();\n const codeLookup = new Map<string, Requirement>();\n for (const req of docsRequirements) {\n docsLookup.set(req.id, req);\n }\n for (const feat of codeFeatures) {\n codeLookup.set(feat.id, feat);\n }\n\n // Post-process: merge descriptions from original data if AI didn't include them\n const enrichedReqs = reqs.map((req) => {\n const reqId = req.requirement?.id || req.id || '';\n\n // Try to get description from original requirements/features\n let fallbackDesc = '';\n if (docsLookup.has(reqId)) {\n fallbackDesc = docsLookup.get(reqId)!.description;\n } else if (codeLookup.has(reqId)) {\n fallbackDesc = codeLookup.get(reqId)!.description;\n }\n\n // If AI didn't provide description, use fallback\n const currentDesc = req.requirement?.description || req.description;\n const needsFallback = !currentDesc || currentDesc === 'No description' || currentDesc.length < 10;\n\n if (needsFallback && fallbackDesc) {\n return {\n ...req,\n description: fallbackDesc,\n requirement: req.requirement\n ? { ...req.requirement, description: fallbackDesc }\n : undefined,\n };\n }\n\n return req;\n });\n\n return {\n requirements: enrichedReqs,\n tokensUsed: { input: result.inputTokens, output: result.outputTokens },\n };\n}\n\n// ============================================================================\n// Report Generation\n// ============================================================================\n\n/**\n * Generate a drift report from verification results\n */\nexport function generateDriftReport(\n result: VerificationResult,\n projectPath: string\n): DriftReport {\n const critical: VerifiedRequirement[] = [];\n const high: VerifiedRequirement[] = [];\n const medium: VerifiedRequirement[] = [];\n const low: VerifiedRequirement[] = [];\n const undocumented: VerifiedRequirement[] = [];\n const unimplemented: VerifiedRequirement[] = [];\n\n for (const req of result.requirements) {\n switch (req.status) {\n case 'drift':\n switch (req.drift?.severity) {\n case 'critical':\n critical.push(req);\n break;\n case 'high':\n high.push(req);\n break;\n case 'medium':\n medium.push(req);\n break;\n case 'low':\n low.push(req);\n break;\n }\n break;\n case 'undocumented':\n undocumented.push(req);\n break;\n case 'unimplemented':\n unimplemented.push(req);\n break;\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n projectPath,\n summary: result.summary,\n critical,\n high,\n medium,\n low,\n undocumented,\n unimplemented,\n };\n}\n\n/**\n * Format verification result as markdown\n */\nexport function formatVerificationMarkdown(result: VerificationResult): string {\n const total = result.summary.total || 1; // Prevent division by zero\n const lines: string[] = [\n '# Verification Report',\n '',\n '## Summary',\n '',\n `| Status | Count | Percentage |`,\n `|--------|-------|------------|`,\n `| ✅ Verified | ${result.summary.verified} | ${Math.round((result.summary.verified / total) * 100)}% |`,\n `| ⚠️ Drift | ${result.summary.drift} | ${Math.round((result.summary.drift / total) * 100)}% |`,\n `| ❌ Undocumented | ${result.summary.undocumented} | ${Math.round((result.summary.undocumented / total) * 100)}% |`,\n `| 🔴 Unimplemented | ${result.summary.unimplemented} | ${Math.round((result.summary.unimplemented / total) * 100)}% |`,\n '',\n `**Overall Confidence:** ${result.summary.overallConfidence || 0}%`,\n '',\n ];\n\n // Critical drift section\n if (result.criticalDrift.length > 0) {\n lines.push('## 🚨 Critical Drift');\n lines.push('');\n for (const req of result.criticalDrift) {\n lines.push(`### ${getReqId(req)}: ${getReqDesc(req)}`);\n lines.push(`**Severity:** ${req.drift?.severity?.toUpperCase() || 'CRITICAL'}`);\n lines.push('');\n if (req.documentedBehavior) {\n lines.push(`**Documented:** ${req.documentedBehavior}`);\n }\n if (req.implementedBehavior) {\n lines.push(`**Implemented:** ${req.implementedBehavior}`);\n }\n if (req.drift?.description) {\n lines.push(`**Issue:** ${req.drift.description}`);\n }\n if (req.drift?.recommendation) {\n lines.push(`**Recommendation:** ${req.drift.recommendation.replace(/_/g, ' ')}`);\n }\n lines.push('');\n }\n }\n\n // Verified requirements\n const verified = result.requirements.filter((r) => r.status === 'verified');\n if (verified.length > 0) {\n lines.push('## ✅ Verified Requirements');\n lines.push('');\n for (const req of verified) {\n lines.push(`- **${getReqId(req)}:** ${getReqDesc(req)} (${req.confidence || 0}% confidence)`);\n }\n lines.push('');\n }\n\n // Drift (non-critical)\n const drift = result.requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity !== 'critical'\n );\n if (drift.length > 0) {\n lines.push('## ⚠️ Drift Detected');\n lines.push('');\n for (const req of drift) {\n lines.push(`### ${getReqId(req)}: ${getReqDesc(req)}`);\n lines.push(`**Severity:** ${req.drift?.severity || 'medium'}`);\n if (req.drift?.description) {\n lines.push(`**Issue:** ${req.drift.description}`);\n }\n lines.push('');\n }\n }\n\n // Undocumented\n const undocumented = result.requirements.filter((r) => r.status === 'undocumented');\n if (undocumented.length > 0) {\n lines.push('## ❌ Undocumented Features');\n lines.push('');\n lines.push('These features exist in code but are not documented:');\n lines.push('');\n for (const req of undocumented) {\n lines.push(`- **${getReqId(req)}:** ${getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n // Unimplemented\n const unimplemented = result.requirements.filter((r) => r.status === 'unimplemented');\n if (unimplemented.length > 0) {\n lines.push('## 🔴 Unimplemented Requirements');\n lines.push('');\n lines.push('These requirements are documented but not implemented:');\n lines.push('');\n for (const req of unimplemented) {\n lines.push(`- **${getReqId(req)}:** ${getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format drift report as markdown\n */\nexport function formatDriftReportMarkdown(report: DriftReport): string {\n const total = report.summary.total || 1; // Prevent division by zero\n const lines: string[] = [\n '# Drift Report',\n '',\n `**Generated:** ${report.generatedAt}`,\n `**Project:** ${report.projectPath}`,\n '',\n '## Summary',\n '',\n `- **Total Requirements:** ${report.summary.total}`,\n `- **Verified:** ${report.summary.verified} (${Math.round((report.summary.verified / total) * 100)}%)`,\n `- **Drift:** ${report.summary.drift}`,\n `- **Undocumented:** ${report.summary.undocumented}`,\n `- **Unimplemented:** ${report.summary.unimplemented}`,\n `- **Overall Confidence:** ${report.summary.overallConfidence || 0}%`,\n '',\n ];\n\n // Critical section\n if (report.critical.length > 0) {\n lines.push('## 🔴 Critical Drift (Requires Immediate Attention)');\n lines.push('');\n for (const req of report.critical) {\n lines.push(`### ${getReqId(req)}: ${getReqDesc(req)}`);\n lines.push('');\n if (req.documentedBehavior) {\n lines.push(`**Documented:** ${req.documentedBehavior}`);\n }\n if (req.implementedBehavior) {\n lines.push(`**Implemented:** ${req.implementedBehavior}`);\n }\n if (req.drift?.description) {\n lines.push(`**Issue:** ${req.drift.description}`);\n }\n lines.push('');\n }\n }\n\n // High severity\n if (report.high.length > 0) {\n lines.push('## 🟠 High Severity Drift');\n lines.push('');\n for (const req of report.high) {\n lines.push(`- **${getReqId(req)}:** ${req.drift?.description || getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n // Medium severity\n if (report.medium.length > 0) {\n lines.push('## 🟡 Medium Severity Drift');\n lines.push('');\n for (const req of report.medium) {\n lines.push(`- **${getReqId(req)}:** ${req.drift?.description || getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n // Undocumented features\n if (report.undocumented.length > 0) {\n lines.push('## ❌ Undocumented Features');\n lines.push('');\n lines.push('Features found in code but not in documentation:');\n lines.push('');\n for (const req of report.undocumented) {\n lines.push(`- ${getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n // Unimplemented requirements\n if (report.unimplemented.length > 0) {\n lines.push('## 🔴 Unimplemented Requirements');\n lines.push('');\n lines.push('Requirements in documentation but not found in code:');\n lines.push('');\n for (const req of report.unimplemented) {\n lines.push(`- ${getReqDesc(req)}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * VasperaPM Analyze Command\n *\n * Orchestrates the full analysis pipeline:\n * 1. Discover all docs and code\n * 2. Extract requirements from docs\n * 3. Extract features from code\n * 4. Cross-validate and verify\n * 5. Output verified spec and drift report\n */\n\nimport { resolve } from 'path';\nimport { writeFileSync, existsSync } from 'fs';\nimport {\n discoverProject,\n formatDiscoverySummary,\n getAllDocsContent,\n getCodeContent,\n type DiscoveryResult,\n} from '../discovery/index.js';\nimport {\n verify,\n generateDriftReport,\n formatVerificationMarkdown,\n formatDriftReportMarkdown,\n type VerificationResult,\n type DriftReport,\n} from '../verification/index.js';\nimport {\n detectOutputPath,\n initializeOutputFolder,\n} from '../output/folder-manager.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AnalyzeOptions {\n /** Output directory (default: auto-detect) */\n output?: string;\n /** Run in CI mode (no colors, exit codes) */\n ci?: boolean;\n /** Verbose output */\n verbose?: boolean;\n /** Skip verification (discovery only) */\n discoveryOnly?: boolean;\n /** Maximum total tokens to use */\n maxTokens?: number;\n}\n\nexport interface AnalyzeResult {\n discovery: DiscoveryResult;\n verification?: VerificationResult;\n driftReport?: DriftReport;\n outputPath: string;\n savedFiles: string[];\n tokensUsed: number;\n success: boolean;\n errors: string[];\n}\n\n// ============================================================================\n// Console Helpers\n// ============================================================================\n\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[36m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n};\n\nfunction log(message: string, ci: boolean = false): void {\n if (ci) {\n // Strip ANSI codes for CI\n console.log(message.replace(/\\x1b\\[[0-9;]*m/g, ''));\n } else {\n console.log(message);\n }\n}\n\nfunction spinner(message: string, ci: boolean = false): void {\n if (!ci) {\n process.stdout.write(`${colors.blue}◐${colors.reset} ${message}...`);\n } else {\n console.log(message + '...');\n }\n}\n\nfunction spinnerDone(result: string, ci: boolean = false): void {\n if (!ci) {\n process.stdout.write(`\\r${colors.green}✓${colors.reset} ${result}\\n`);\n } else {\n console.log(' ' + result);\n }\n}\n\nfunction spinnerFail(result: string, ci: boolean = false): void {\n if (!ci) {\n process.stdout.write(`\\r${colors.red}✗${colors.reset} ${result}\\n`);\n } else {\n console.log(' ERROR: ' + result);\n }\n}\n\n// ============================================================================\n// Main Analyze Function\n// ============================================================================\n\n/**\n * Run the full analysis pipeline on a project\n */\nexport async function analyze(\n projectPath: string,\n options: AnalyzeOptions = {}\n): Promise<AnalyzeResult> {\n const {\n output,\n ci = false,\n verbose = false,\n discoveryOnly = false,\n maxTokens = 200000,\n } = options;\n\n const errors: string[] = [];\n const savedFiles: string[] = [];\n let tokensUsed = 0;\n\n // Resolve project path\n const resolvedPath = resolve(projectPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`Project path does not exist: ${resolvedPath}`);\n }\n\n // Determine output path\n const outputPath = output ? resolve(output) : detectOutputPath(resolvedPath);\n\n // Print header\n if (!ci) {\n log(`\n${colors.blue}╔═══════════════════════════════════════════════════════════════╗\n║ ║\n║ ${colors.bold}VasperaPM Analyzer${colors.reset}${colors.blue} ║\n║ ${colors.dim}Creating verified specifications${colors.reset}${colors.blue} ║\n║ ║\n╚═══════════════════════════════════════════════════════════════╝${colors.reset}\n`);\n }\n\n log(`${colors.bold}Project:${colors.reset} ${resolvedPath}`, ci);\n log(`${colors.bold}Output:${colors.reset} ${outputPath}`, ci);\n log('', ci);\n\n // =========================================================================\n // Phase 1: Discovery\n // =========================================================================\n\n spinner('Discovering documentation and code', ci);\n\n let discovery: DiscoveryResult;\n try {\n discovery = await discoverProject(resolvedPath, {\n includeContent: true,\n maxFileSize: 512 * 1024, // 512KB per file\n });\n\n spinnerDone(\n `Found ${discovery.summary.totalDocs} docs, ${discovery.summary.totalCode} code files`,\n ci\n );\n\n if (verbose) {\n log('', ci);\n log(formatDiscoverySummary(discovery), ci);\n log('', ci);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n spinnerFail(`Discovery failed: ${message}`, ci);\n errors.push(`Discovery failed: ${message}`);\n\n return {\n discovery: {\n projectRoot: resolvedPath,\n docs: [],\n code: [],\n summary: {\n totalDocs: 0,\n totalCode: 0,\n docsByCategory: {\n readme: 0,\n prd: 0,\n api: 0,\n architecture: 0,\n changelog: 0,\n contributing: 0,\n other: 0,\n },\n codeByLanguage: {},\n },\n },\n outputPath,\n savedFiles,\n tokensUsed,\n success: false,\n errors,\n };\n }\n\n // Initialize output folder\n initializeOutputFolder(resolvedPath);\n\n // If discovery only, stop here\n if (discoveryOnly) {\n // Ensure discovery directory exists\n const discoveryDir = `${outputPath}/discovery`;\n if (!existsSync(discoveryDir)) {\n const { mkdirSync } = await import('fs');\n mkdirSync(discoveryDir, { recursive: true });\n }\n\n // Save discovery report\n const discoveryReport = generateDiscoveryReport(discovery);\n const discoveryPath = `${discoveryDir}/inventory_v1.0.md`;\n writeFileSync(discoveryPath, addMetadataHeader(discoveryReport, 'discover_docs', 0));\n savedFiles.push(discoveryPath);\n\n log('', ci);\n log(`${colors.green}✓${colors.reset} Discovery complete (skipped verification)`, ci);\n log(`${colors.bold}Output:${colors.reset} ${outputPath}`, ci);\n\n return {\n discovery,\n outputPath,\n savedFiles,\n tokensUsed,\n success: true,\n errors,\n };\n }\n\n // =========================================================================\n // Phase 2: Content Extraction\n // =========================================================================\n\n spinner('Extracting documentation content', ci);\n\n const docsContent = getAllDocsContent(discovery.docs, maxTokens / 2);\n if (!docsContent || docsContent.length < 100) {\n spinnerFail('No documentation content found', ci);\n errors.push('No documentation content found');\n } else {\n spinnerDone(`Extracted ${Math.round(docsContent.length / 1000)}KB of documentation`, ci);\n }\n\n spinner('Extracting code content', ci);\n\n const codeContent = getCodeContent(discovery.code, maxTokens / 2);\n if (!codeContent || codeContent.length < 100) {\n spinnerFail('No code content found', ci);\n errors.push('No code content found');\n } else {\n spinnerDone(`Extracted ${Math.round(codeContent.length / 1000)}KB of code`, ci);\n }\n\n // =========================================================================\n // Phase 3: Verification\n // =========================================================================\n\n if (!docsContent || !codeContent) {\n log('', ci);\n log(`${colors.red}✗${colors.reset} Cannot verify: missing docs or code content`, ci);\n\n return {\n discovery,\n outputPath,\n savedFiles,\n tokensUsed,\n success: false,\n errors,\n };\n }\n\n spinner('Cross-validating docs vs code (this may take a minute)', ci);\n\n let verification: VerificationResult;\n try {\n verification = await verify(docsContent, codeContent);\n tokensUsed = verification.tokensUsed.input + verification.tokensUsed.output;\n\n spinnerDone(\n `Verified ${verification.summary.total} requirements (${verification.summary.verified} verified, ${verification.summary.drift} drift)`,\n ci\n );\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n spinnerFail(`Verification failed: ${message}`, ci);\n errors.push(`Verification failed: ${message}`);\n\n return {\n discovery,\n outputPath,\n savedFiles,\n tokensUsed,\n success: false,\n errors,\n };\n }\n\n // =========================================================================\n // Phase 4: Output Generation\n // =========================================================================\n\n log('', ci);\n spinner('Generating verified specification', ci);\n\n // Save verified spec\n const verifiedSpec = formatVerificationMarkdown(verification);\n const verifiedSpecPath = `${outputPath}/verified-spec/spec_v1.0.md`;\n try {\n const verifiedDir = `${outputPath}/verified-spec`;\n if (!existsSync(verifiedDir)) {\n const { mkdirSync } = await import('fs');\n mkdirSync(verifiedDir, { recursive: true });\n }\n writeFileSync(verifiedSpecPath, addMetadataHeader(verifiedSpec, 'verify_spec', tokensUsed));\n savedFiles.push(verifiedSpecPath);\n spinnerDone(`Saved verified-spec/spec_v1.0.md`, ci);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n spinnerFail(`Failed to save verified spec: ${message}`, ci);\n errors.push(`Failed to save verified spec: ${message}`);\n }\n\n // Generate and save drift report\n spinner('Generating drift report', ci);\n\n const driftReport = generateDriftReport(verification, resolvedPath);\n const driftMarkdown = formatDriftReportMarkdown(driftReport);\n const driftPath = `${outputPath}/drift-reports/drift_${new Date().toISOString().split('T')[0]}.md`;\n try {\n const driftDir = `${outputPath}/drift-reports`;\n if (!existsSync(driftDir)) {\n const { mkdirSync } = await import('fs');\n mkdirSync(driftDir, { recursive: true });\n }\n writeFileSync(driftPath, addMetadataHeader(driftMarkdown, 'drift_report', 0));\n savedFiles.push(driftPath);\n spinnerDone(`Saved drift-reports/drift_${new Date().toISOString().split('T')[0]}.md`, ci);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n spinnerFail(`Failed to save drift report: ${message}`, ci);\n errors.push(`Failed to save drift report: ${message}`);\n }\n\n // Save discovery report\n spinner('Generating discovery inventory', ci);\n\n const discoveryReport = generateDiscoveryReport(discovery);\n const discoveryDir = `${outputPath}/discovery`;\n const discoveryPath = `${discoveryDir}/inventory_v1.0.md`;\n try {\n if (!existsSync(discoveryDir)) {\n const { mkdirSync } = await import('fs');\n mkdirSync(discoveryDir, { recursive: true });\n }\n writeFileSync(discoveryPath, addMetadataHeader(discoveryReport, 'discover_docs', 0));\n savedFiles.push(discoveryPath);\n spinnerDone(`Saved discovery/inventory_v1.0.md`, ci);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n spinnerFail(`Failed to save discovery report: ${message}`, ci);\n }\n\n // =========================================================================\n // Final Summary\n // =========================================================================\n\n log('', ci);\n log(`${colors.bold}═══════════════════════════════════════════════════════════════${colors.reset}`, ci);\n log('', ci);\n\n // Summary table\n const summaryLines = [\n `${colors.bold}Results:${colors.reset}`,\n ` ${colors.green}✅ Verified:${colors.reset} ${verification.summary.verified} requirements (${Math.round((verification.summary.verified / verification.summary.total) * 100)}%)`,\n ` ${colors.yellow}⚠️ Drift:${colors.reset} ${verification.summary.drift} requirements`,\n ` ${colors.red}❌ Undocumented:${colors.reset} ${verification.summary.undocumented} features`,\n ` ${colors.magenta}🔴 Unimplemented:${colors.reset} ${verification.summary.unimplemented} requirements`,\n '',\n `${colors.bold}Confidence:${colors.reset} ${verification.summary.overallConfidence}%`,\n '',\n `${colors.bold}Output saved to:${colors.reset} ${outputPath}`,\n ];\n\n for (const line of summaryLines) {\n log(line, ci);\n }\n\n // Critical drift warning\n if (verification.criticalDrift.length > 0) {\n log('', ci);\n log(`${colors.red}${colors.bold}⚠️ CRITICAL DRIFT DETECTED${colors.reset}`, ci);\n log(`${colors.red}Found ${verification.criticalDrift.length} critical issues requiring immediate attention.${colors.reset}`, ci);\n log(`See: ${driftPath}`, ci);\n }\n\n log('', ci);\n\n return {\n discovery,\n verification,\n driftReport,\n outputPath,\n savedFiles,\n tokensUsed,\n success: errors.length === 0,\n errors,\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Add YAML metadata header to content\n */\nfunction addMetadataHeader(content: string, tool: string, tokensUsed: number): string {\n const header = `---\nvasperaPM:\n tool: ${tool}\n version: 2.0.0\n generated: ${new Date().toISOString()}\n tokens_used: ${tokensUsed}\n---\n\n`;\n return header + content;\n}\n\n/**\n * Generate discovery report markdown\n */\nfunction generateDiscoveryReport(discovery: DiscoveryResult): string {\n const lines: string[] = [\n '# Discovery Inventory',\n '',\n `**Project:** ${discovery.projectRoot}`,\n `**Generated:** ${new Date().toISOString()}`,\n '',\n '## Summary',\n '',\n `- **Documentation Files:** ${discovery.summary.totalDocs}`,\n `- **Code Files:** ${discovery.summary.totalCode}`,\n '',\n '## Documentation by Category',\n '',\n ];\n\n for (const [category, count] of Object.entries(discovery.summary.docsByCategory)) {\n if (count > 0) {\n lines.push(`- **${category}:** ${count} files`);\n }\n }\n\n lines.push('');\n lines.push('## Code by Language');\n lines.push('');\n\n for (const [language, count] of Object.entries(discovery.summary.codeByLanguage)) {\n lines.push(`- **${language}:** ${count} files`);\n }\n\n lines.push('');\n lines.push('## Documentation Files');\n lines.push('');\n\n for (const doc of discovery.docs) {\n lines.push(`- \\`${doc.relativePath}\\` (${doc.category})`);\n }\n\n lines.push('');\n lines.push('## Key Code Files');\n lines.push('');\n\n // Group by category\n const codeByCategory: Record<string, typeof discovery.code> = {};\n for (const file of discovery.code) {\n if (!codeByCategory[file.category]) {\n codeByCategory[file.category] = [];\n }\n codeByCategory[file.category].push(file);\n }\n\n for (const [category, files] of Object.entries(codeByCategory)) {\n lines.push(`### ${category}`);\n lines.push('');\n for (const file of files.slice(0, 10)) {\n lines.push(`- \\`${file.relativePath}\\``);\n }\n if (files.length > 10) {\n lines.push(`- ... and ${files.length - 10} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Quick verify command for CI (returns exit code)\n */\nexport async function quickVerify(\n projectPath: string,\n options: AnalyzeOptions = {}\n): Promise<number> {\n const result = await analyze(projectPath, { ...options, ci: true });\n\n if (!result.success) {\n return 2; // Error during analysis\n }\n\n if (result.verification?.criticalDrift.length ?? 0 > 0) {\n return 1; // Critical drift found\n }\n\n return 0; // Success\n}\n","#!/usr/bin/env node\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { homedir } from 'os';\nimport { join, resolve } from 'path';\nimport { createInterface } from 'readline';\n\n// ASCII Art Banner\nconst BANNER = `\n\\x1b[36m╔═══════════════════════════════════════════════════════════════╗\n║ ║\n║ ██╗ ██╗ █████╗ ███████╗██████╗ ███████╗██████╗ █████╗ ║\n║ ██║ ██║██╔══██╗██╔════╝██╔══██╗██╔════╝██╔══██╗██╔══██╗ ║\n║ ██║ ██║███████║███████╗██████╔╝█████╗ ██████╔╝███████║ ║\n║ ╚██╗ ██╔╝██╔══██║╚════██║██╔═══╝ ██╔══╝ ██╔══██╗██╔══██║ ║\n║ ╚████╔╝ ██║ ██║███████║██║ ███████╗██║ ██║██║ ██║ ║\n║ ╚═══╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ║\n║ ║\n║ \\x1b[33mAI-Powered Verified Specifications\\x1b[36m ║\n║ ║\n╚═══════════════════════════════════════════════════════════════╝\\x1b[0m\n`;\n\nconst VERSION = '2.0.0';\n\nconst HELP = `\n\\x1b[1mUsage:\\x1b[0m vaspera-pm <command> [path] [options]\n\n\\x1b[1mAnalysis Commands:\\x1b[0m\n \\x1b[32manalyze\\x1b[0m <path> Full analysis: discover docs, analyze code, verify\n \\x1b[32mverify\\x1b[0m <path> Quick drift check (for CI/CD pipelines)\n \\x1b[32mdiscover\\x1b[0m <path> Discover docs and code without verification\n\n\\x1b[1mTraceability Commands:\\x1b[0m\n \\x1b[32mregressions\\x1b[0m Detect removed requirements (regression check)\n \\x1b[32msprint-report\\x1b[0m Generate sprint scope change report\n \\x1b[32mestimates\\x1b[0m Track estimate changes over time\n \\x1b[32maudit\\x1b[0m Query the audit trail\n\n\\x1b[1mSetup Commands:\\x1b[0m\n \\x1b[32minit\\x1b[0m Initialize VasperaPM in current project\n \\x1b[32minstall\\x1b[0m Configure VasperaPM with Claude Code\n \\x1b[32mconnect\\x1b[0m Set up your API key and integrations\n \\x1b[32mserve\\x1b[0m Start the MCP server (used by Claude Code)\n \\x1b[32mstatus\\x1b[0m Check your current configuration\n\n\\x1b[1mOptions:\\x1b[0m\n --output <dir> Output directory (default: docs/vasperaPM)\n --ci CI-friendly output (no colors, exit codes)\n --verbose Show detailed progress\n --agents Use multi-agent architecture (debate-enabled verification)\n --no-debate Disable debate for faster results (agents mode only)\n --format <fmt> Output format: markdown (default), json\n --files <list> Comma-separated list of files to analyze (for diff-only mode)\n --help Show this help message\n\n\\x1b[1mExamples:\\x1b[0m\n $ vaspera-pm analyze . # Full analysis of current directory\n $ vaspera-pm analyze . --agents # Use multi-agent with debate\n $ vaspera-pm verify . --ci # CI check with exit codes\n $ vaspera-pm discover ./my-project # Discovery only\n $ vaspera-pm init # Interactive setup wizard\n\n\\x1b[1mEnvironment:\\x1b[0m\n ANTHROPIC_API_KEY Claude API key (required for analysis)\n\n\\x1b[1mDocumentation:\\x1b[0m\n https://github.com/vaspera/vaspera-pm\n`;\n\n// Get Claude config path\nfunction getClaudeConfigPath(): string {\n return join(homedir(), '.claude', 'claude_desktop_config.json');\n}\n\n// Get VasperaPM config path\nfunction getVasperaConfigPath(): string {\n return join(homedir(), '.vasperapm', 'config.json');\n}\n\n// Read JSON file safely\nfunction readJsonFile(path: string): Record<string, unknown> | null {\n try {\n if (!existsSync(path)) return null;\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n}\n\n// Write JSON file safely\nfunction writeJsonFile(path: string, data: Record<string, unknown>): void {\n const dir = path.substring(0, path.lastIndexOf('/'));\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(path, JSON.stringify(data, null, 2));\n}\n\n// Prompt for input\nfunction prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n// Print success message\nfunction success(message: string): void {\n console.log(`\\x1b[32m✓\\x1b[0m ${message}`);\n}\n\n// Print error message\nfunction error(message: string): void {\n console.log(`\\x1b[31m✗\\x1b[0m ${message}`);\n}\n\n// Print info message\nfunction info(message: string): void {\n console.log(`\\x1b[36mℹ\\x1b[0m ${message}`);\n}\n\n// Print warning message\nfunction warn(message: string): void {\n console.log(`\\x1b[33m⚠\\x1b[0m ${message}`);\n}\n\n// Install command - Configure Claude Code\nasync function install(): Promise<void> {\n console.log(BANNER);\n console.log('\\x1b[1mInstalling VasperaPM for Claude Code...\\x1b[0m\\n');\n\n const configPath = getClaudeConfigPath();\n let config = readJsonFile(configPath) as { mcpServers?: Record<string, unknown> } | null;\n\n if (!config) {\n config = { mcpServers: {} };\n info('Creating Claude Code configuration...');\n }\n\n if (!config.mcpServers) {\n config.mcpServers = {};\n }\n\n // Check if already installed\n if (config.mcpServers['vaspera-pm']) {\n warn('VasperaPM is already installed in Claude Code.');\n const answer = await prompt('\\nDo you want to reinstall? (y/N): ');\n if (answer.toLowerCase() !== 'y') {\n info('Installation cancelled.');\n return;\n }\n }\n\n // Get API key\n const vasperaConfig = readJsonFile(getVasperaConfigPath()) as { apiKey?: string } | null;\n let apiKey = vasperaConfig?.apiKey || process.env.VASPERA_API_KEY || '';\n\n if (!apiKey) {\n console.log('\\n\\x1b[1mAPI Key Setup\\x1b[0m');\n console.log('Get your API key at: \\x1b[36mhttps://vasperapm.com/dashboard\\x1b[0m\\n');\n apiKey = await prompt('Enter your VasperaPM API key (or press Enter to use test mode): ');\n\n if (!apiKey) {\n apiKey = 'vpm_test_local_development_key_for_testing';\n info('Using test mode API key (limited features)');\n }\n }\n\n // Add VasperaPM to Claude config\n config.mcpServers['vaspera-pm'] = {\n command: 'vasperapm',\n args: ['serve'],\n env: {\n VASPERA_API_KEY: apiKey,\n NODE_ENV: apiKey.includes('test') ? 'development' : 'production',\n },\n };\n\n writeJsonFile(configPath, config);\n\n // Save API key to VasperaPM config\n const vasperaDir = join(homedir(), '.vasperapm');\n if (!existsSync(vasperaDir)) {\n mkdirSync(vasperaDir, { recursive: true });\n }\n writeJsonFile(getVasperaConfigPath(), { apiKey });\n\n console.log('\\n');\n success('VasperaPM installed successfully!');\n console.log('\\n\\x1b[1mNext steps:\\x1b[0m');\n console.log(' 1. Restart Claude Code (or VSCode)');\n console.log(' 2. Look for VasperaPM tools in the MCP panel');\n console.log(' 3. Try: \"Generate a PRD for a todo app\"\\n');\n\n console.log('\\x1b[1mAvailable Tools:\\x1b[0m');\n console.log(' \\x1b[33m•\\x1b[0m generate_prd - Create PRDs from context');\n console.log(' \\x1b[33m•\\x1b[0m infer_prd_from_code - Analyze code to generate PRD');\n console.log(' \\x1b[33m•\\x1b[0m generate_code - Generate code from PRD');\n console.log(' \\x1b[33m•\\x1b[0m sync_jira/linear/github - Sync with PM tools');\n console.log(' \\x1b[33m•\\x1b[0m generate_api_spec - Create OpenAPI specs');\n console.log(' \\x1b[33m•\\x1b[0m generate_test_cases - Create test plans\\n');\n}\n\n// Connect command - Set up API key and integrations\nasync function connect(): Promise<void> {\n console.log(BANNER);\n console.log('\\x1b[1mConnect VasperaPM to your services...\\x1b[0m\\n');\n\n // API Key setup\n console.log('\\x1b[1m1. API Key\\x1b[0m');\n const vasperaConfig = readJsonFile(getVasperaConfigPath()) as { apiKey?: string } | null;\n\n if (vasperaConfig?.apiKey) {\n const masked = vasperaConfig.apiKey.substring(0, 12) + '...' + vasperaConfig.apiKey.substring(vasperaConfig.apiKey.length - 4);\n info(`Current API key: ${masked}`);\n const answer = await prompt('Update API key? (y/N): ');\n if (answer.toLowerCase() !== 'y') {\n success('Keeping existing API key');\n } else {\n const newKey = await prompt('Enter new API key: ');\n if (newKey) {\n writeJsonFile(getVasperaConfigPath(), { ...vasperaConfig, apiKey: newKey });\n success('API key updated');\n }\n }\n } else {\n console.log('Get your API key at: \\x1b[36mhttps://vasperapm.com/dashboard\\x1b[0m\\n');\n const apiKey = await prompt('Enter your VasperaPM API key: ');\n if (apiKey) {\n writeJsonFile(getVasperaConfigPath(), { apiKey });\n success('API key saved');\n } else {\n warn('No API key provided. Some features will be limited.');\n }\n }\n\n console.log('\\n\\x1b[1m2. Integrations\\x1b[0m');\n console.log('Configure integrations at: \\x1b[36mhttps://vasperapm.com/dashboard/integrations\\x1b[0m\\n');\n console.log(' \\x1b[33m•\\x1b[0m Jira - Sync PRDs to Jira epics/stories');\n console.log(' \\x1b[33m•\\x1b[0m Linear - Export tasks to Linear projects');\n console.log(' \\x1b[33m•\\x1b[0m GitHub - Create issues and track progress\\n');\n\n success('Connection setup complete!');\n console.log('\\nRun \\x1b[36mvasperapm status\\x1b[0m to check your configuration.\\n');\n}\n\n// Status command - Check configuration\nasync function status(): Promise<void> {\n console.log(BANNER);\n console.log('\\x1b[1mVasperaPM Status\\x1b[0m\\n');\n\n // Check VasperaPM config\n const vasperaConfig = readJsonFile(getVasperaConfigPath()) as { apiKey?: string } | null;\n if (vasperaConfig?.apiKey) {\n const masked = vasperaConfig.apiKey.substring(0, 12) + '...' + vasperaConfig.apiKey.substring(vasperaConfig.apiKey.length - 4);\n success(`API Key: ${masked}`);\n\n if (vasperaConfig.apiKey.includes('_live_')) {\n info('Mode: Production');\n } else if (vasperaConfig.apiKey.includes('_test_')) {\n info('Mode: Test/Development');\n }\n } else {\n warn('API Key: Not configured');\n console.log(' Run \\x1b[36mvasperapm connect\\x1b[0m to set up your API key\\n');\n }\n\n // Check Claude Code config\n const claudeConfig = readJsonFile(getClaudeConfigPath()) as { mcpServers?: Record<string, unknown> } | null;\n if (claudeConfig?.mcpServers?.['vaspera-pm']) {\n success('Claude Code: Installed');\n } else {\n warn('Claude Code: Not installed');\n console.log(' Run \\x1b[36mvasperapm install\\x1b[0m to set up Claude Code integration\\n');\n }\n\n // Version info\n console.log(`\\n\\x1b[1mVersion:\\x1b[0m ${VERSION}`);\n console.log('\\x1b[1mDocs:\\x1b[0m https://github.com/rcolkitt/VasperaPM\\n');\n}\n\n// Serve command - Start MCP server\nasync function serve(): Promise<void> {\n // Import and run the MCP server\n const { startServer } = await import('./server.js');\n await startServer();\n}\n\n// Parse CLI options\nfunction parseOptions(args: string[]): {\n path: string;\n output?: string;\n ci: boolean;\n verbose: boolean;\n agents: boolean;\n debate: boolean;\n format: 'markdown' | 'json';\n files?: string[];\n} {\n let path = '.';\n let output: string | undefined;\n let ci = false;\n let verbose = false;\n let agents = false;\n let debate = true;\n let format: 'markdown' | 'json' = 'markdown';\n let files: string[] | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i] ?? '';\n if (arg === '--output' && args[i + 1]) {\n output = args[++i] ?? '';\n } else if (arg === '--ci') {\n ci = true;\n } else if (arg === '--verbose' || arg === '-v') {\n verbose = true;\n } else if (arg === '--agents') {\n agents = true;\n } else if (arg === '--no-debate') {\n debate = false;\n } else if (arg === '--format' && args[i + 1]) {\n const fmt = args[++i] ?? '';\n if (fmt === 'json' || fmt === 'markdown') {\n format = fmt;\n }\n } else if (arg === '--files' && args[i + 1]) {\n files = (args[++i] ?? '').split(',').filter(Boolean);\n } else if (!arg.startsWith('-') && i === 0) {\n path = arg;\n }\n }\n\n return { path, output, ci, verbose, agents, debate, format, files };\n}\n\n// Analyze command - Full analysis pipeline\nasync function runAnalyze(args: string[]): Promise<void> {\n const options = parseOptions(args);\n\n // Check for API key\n if (!process.env.ANTHROPIC_API_KEY) {\n error('ANTHROPIC_API_KEY environment variable is required');\n console.log('\\nSet your API key:');\n console.log(' export ANTHROPIC_API_KEY=sk-ant-xxx');\n console.log('\\nOr get one at: https://console.anthropic.com\\n');\n process.exit(1);\n }\n\n // Use multi-agent system if --agents flag is set\n if (options.agents) {\n await runAgentAnalyze(options);\n return;\n }\n\n // Legacy single-shot analysis\n const { analyze } = await import('./analyze/index.js');\n const result = await analyze(options.path, {\n output: options.output,\n ci: options.ci,\n verbose: options.verbose,\n });\n\n if (!result.success) {\n process.exit(1);\n }\n\n if (result.verification?.criticalDrift.length ?? 0 > 0) {\n process.exit(options.ci ? 1 : 0);\n }\n}\n\n// Agent-based analysis\nasync function runAgentAnalyze(options: ReturnType<typeof parseOptions>): Promise<void> {\n const { resolve } = await import('path');\n const { existsSync, writeFileSync, mkdirSync } = await import('fs');\n const { runAgentVerification } = await import('./agents/index.js');\n const { detectOutputPath } = await import('./output/folder-manager.js');\n\n const projectPath = resolve(options.path);\n const outputPath = options.output ? resolve(options.output) : detectOutputPath(projectPath);\n\n // Print header\n if (!options.ci) {\n console.log(`\n\\x1b[35m╔═══════════════════════════════════════════════════════════════╗\n║ ║\n║ \\x1b[1mVasperaPM Multi-Agent Analyzer\\x1b[0m\\x1b[35m ║\n║ \\x1b[2mDebate-enabled verification\\x1b[0m\\x1b[35m ║\n║ ║\n╚═══════════════════════════════════════════════════════════════╝\\x1b[0m\n`);\n console.log(`\\x1b[1mProject:\\x1b[0m ${projectPath}`);\n console.log(`\\x1b[1mOutput:\\x1b[0m ${outputPath}`);\n console.log(`\\x1b[1mDebate:\\x1b[0m ${options.debate ? 'Enabled' : 'Disabled'}`);\n console.log('');\n }\n\n try {\n const result = await runAgentVerification(projectPath, outputPath, {\n enableDebate: options.debate,\n verbose: options.verbose,\n onProgress: options.ci ? undefined : (phase, percent, message) => {\n process.stdout.write(`\\r\\x1b[36m[${phase}]\\x1b[0m ${percent}% - ${message.padEnd(60)}`);\n if (percent === 100) console.log('');\n },\n });\n\n // Save results\n const verifiedSpecDir = `${outputPath}/verified-spec`;\n const driftReportDir = `${outputPath}/drift-reports`;\n\n if (!existsSync(verifiedSpecDir)) mkdirSync(verifiedSpecDir, { recursive: true });\n if (!existsSync(driftReportDir)) mkdirSync(driftReportDir, { recursive: true });\n\n // Generate verified spec markdown\n const specMarkdown = generateAgentSpecMarkdown(result);\n writeFileSync(`${verifiedSpecDir}/spec_v1.0.md`, specMarkdown);\n\n // Generate drift report\n const driftMarkdown = generateAgentDriftMarkdown(result);\n const dateStr = new Date().toISOString().split('T')[0];\n writeFileSync(`${driftReportDir}/drift_${dateStr}.md`, driftMarkdown);\n\n // Generate JSON result for CI/Action use\n const summary = result.analysis.summary;\n const jsonResult = {\n verified: summary.verified,\n drift: summary.drift,\n undocumented: summary.undocumented,\n unimplemented: summary.unimplemented,\n confidence: summary.overallConfidence,\n debatesTriggered: summary.debatesTriggered,\n debatesOverturned: summary.debatesOverturned,\n driftFindings: result.analysis.requirements\n .filter((r) => r.status === 'drift' && r.drift)\n .map((r) => ({\n id: r.requirement.id,\n description: r.drift?.description || r.requirement.description,\n severity: r.drift?.severity || 'medium',\n category: r.requirement.category,\n file: r.requirement.sourceFile,\n line: r.requirement.sourceLine,\n documentedBehavior: r.documentedBehavior,\n implementedBehavior: r.implementedBehavior,\n recommendation: r.drift?.recommendation,\n })),\n tokensUsed: result.tokensUsed.input + result.tokensUsed.output,\n executionTimeMs: result.executionTime,\n };\n writeFileSync(`${outputPath}/verification-result.json`, JSON.stringify(jsonResult, null, 2));\n\n // If JSON format requested, output to stdout and exit\n if (options.format === 'json') {\n console.log(JSON.stringify(jsonResult, null, 2));\n if (jsonResult.driftFindings.some((d) => d.severity === 'critical') && options.ci) {\n process.exit(1);\n }\n return;\n }\n\n // Print summary\n if (!options.ci) {\n const summary = result.analysis.summary;\n console.log('');\n console.log('\\x1b[1m═══════════════════════════════════════════════════════════════\\x1b[0m');\n console.log('');\n console.log('\\x1b[1mResults:\\x1b[0m');\n console.log(` \\x1b[32m✅ Verified:\\x1b[0m ${summary.verified} requirements`);\n console.log(` \\x1b[33m⚠️ Drift:\\x1b[0m ${summary.drift} requirements`);\n console.log(` \\x1b[31m❌ Undocumented:\\x1b[0m ${summary.undocumented} features`);\n console.log(` \\x1b[35m🔴 Unimplemented:\\x1b[0m ${summary.unimplemented} requirements`);\n if (summary.disputed > 0) {\n console.log(` \\x1b[36m❓ Disputed:\\x1b[0m ${summary.disputed} (need review)`);\n }\n console.log('');\n console.log(`\\x1b[1mConfidence:\\x1b[0m ${summary.overallConfidence}%`);\n if (summary.debatesTriggered > 0) {\n console.log(`\\x1b[1mDebates:\\x1b[0m ${summary.debatesTriggered} triggered, ${summary.debatesOverturned} overturned`);\n }\n console.log('');\n console.log(`\\x1b[1mTokens used:\\x1b[0m ${result.tokensUsed.input + result.tokensUsed.output}`);\n console.log(`\\x1b[1mExecution time:\\x1b[0m ${(result.executionTime / 1000).toFixed(1)}s`);\n console.log('');\n console.log(`\\x1b[1mOutput saved to:\\x1b[0m ${outputPath}`);\n console.log('');\n }\n\n // Exit with appropriate code\n const criticalDrift = result.analysis.requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity === 'critical'\n );\n\n if (criticalDrift.length > 0 && options.ci) {\n process.exit(1);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error';\n error(`Agent analysis failed: ${message}`);\n if (options.verbose) {\n console.error(err);\n }\n process.exit(1);\n }\n}\n\n// Generate verified spec markdown from agent results\nfunction generateAgentSpecMarkdown(result: Awaited<ReturnType<typeof import('./agents/index.js').runAgentVerification>>): string {\n const summary = result.analysis.summary;\n const total = summary.total || 1;\n\n const lines: string[] = [\n '---',\n 'vasperaPM:',\n ' tool: agent_verification',\n ' version: 3.0.0',\n ` generated: ${new Date().toISOString()}`,\n ` tokens_used: ${result.tokensUsed.input + result.tokensUsed.output}`,\n ` debate_enabled: true`,\n ` debates_triggered: ${summary.debatesTriggered}`,\n '---',\n '',\n '# Verification Report (Multi-Agent)',\n '',\n '## Summary',\n '',\n '| Status | Count | Percentage |',\n '|--------|-------|------------|',\n `| ✅ Verified | ${summary.verified} | ${Math.round((summary.verified / total) * 100)}% |`,\n `| ⚠️ Drift | ${summary.drift} | ${Math.round((summary.drift / total) * 100)}% |`,\n `| ❌ Undocumented | ${summary.undocumented} | ${Math.round((summary.undocumented / total) * 100)}% |`,\n `| 🔴 Unimplemented | ${summary.unimplemented} | ${Math.round((summary.unimplemented / total) * 100)}% |`,\n '',\n `**Overall Confidence:** ${summary.overallConfidence}%`,\n `**Debates Triggered:** ${summary.debatesTriggered}`,\n `**Findings Overturned:** ${summary.debatesOverturned}`,\n '',\n ];\n\n // Add debated items if any\n const debated = result.analysis.requirements.filter((r) => r.debate);\n if (debated.length > 0) {\n lines.push('## 🔄 Debated Findings');\n lines.push('');\n lines.push('These findings were challenged and debated by the validator agent:');\n lines.push('');\n for (const req of debated) {\n lines.push(`### ${req.requirement.id}: ${req.requirement.description.substring(0, 100)}`);\n lines.push(`- **Outcome:** ${req.debate!.outcome}`);\n lines.push(`- **Final Confidence:** ${req.debate!.finalConfidence}%`);\n lines.push(`- **Rounds:** ${req.debate!.rounds.length}`);\n lines.push('');\n }\n }\n\n // Add verified requirements\n const verified = result.analysis.requirements.filter((r) => r.status === 'verified');\n if (verified.length > 0) {\n lines.push('## ✅ Verified Requirements');\n lines.push('');\n for (const req of verified) {\n lines.push(`- **${req.requirement.id}:** ${req.requirement.description} (${req.confidence}% confidence)`);\n }\n lines.push('');\n }\n\n // Add drift\n const drift = result.analysis.requirements.filter((r) => r.status === 'drift');\n if (drift.length > 0) {\n lines.push('## ⚠️ Drift Detected');\n lines.push('');\n for (const req of drift) {\n lines.push(`### ${req.requirement.id}: ${req.requirement.description}`);\n lines.push(`**Severity:** ${req.drift?.severity || 'medium'}`);\n if (req.drift?.description) {\n lines.push(`**Issue:** ${req.drift.description}`);\n }\n if (req.drift?.recommendation) {\n lines.push(`**Recommendation:** ${req.drift.recommendation.replace(/_/g, ' ')}`);\n }\n lines.push('');\n }\n }\n\n return lines.join('\\n');\n}\n\n// Generate drift report markdown from agent results\nfunction generateAgentDriftMarkdown(result: Awaited<ReturnType<typeof import('./agents/index.js').runAgentVerification>>): string {\n const summary = result.analysis.summary;\n const total = summary.total || 1;\n\n const lines: string[] = [\n '---',\n 'vasperaPM:',\n ' tool: agent_drift_report',\n ' version: 3.0.0',\n ` generated: ${new Date().toISOString()}`,\n '---',\n '',\n '# Drift Report (Multi-Agent)',\n '',\n `**Generated:** ${new Date().toISOString()}`,\n '',\n '## Summary',\n '',\n `- **Total Requirements:** ${summary.total}`,\n `- **Verified:** ${summary.verified} (${Math.round((summary.verified / total) * 100)}%)`,\n `- **Drift:** ${summary.drift}`,\n `- **Undocumented:** ${summary.undocumented}`,\n `- **Unimplemented:** ${summary.unimplemented}`,\n `- **Overall Confidence:** ${summary.overallConfidence}%`,\n '',\n ];\n\n // Critical drift\n const critical = result.analysis.requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity === 'critical'\n );\n if (critical.length > 0) {\n lines.push('## 🔴 Critical Drift');\n lines.push('');\n for (const req of critical) {\n lines.push(`### ${req.requirement.id}: ${req.requirement.description}`);\n if (req.documentedBehavior) lines.push(`**Documented:** ${req.documentedBehavior}`);\n if (req.implementedBehavior) lines.push(`**Implemented:** ${req.implementedBehavior}`);\n if (req.drift?.description) lines.push(`**Issue:** ${req.drift.description}`);\n lines.push('');\n }\n }\n\n // High severity\n const high = result.analysis.requirements.filter(\n (r) => r.status === 'drift' && r.drift?.severity === 'high'\n );\n if (high.length > 0) {\n lines.push('## 🟠 High Severity');\n lines.push('');\n for (const req of high) {\n lines.push(`- **${req.requirement.id}:** ${req.drift?.description || req.requirement.description}`);\n }\n lines.push('');\n }\n\n // Disputed items\n if (result.analysis.disputes.length > 0) {\n lines.push('## ❓ Disputed (Need Review)');\n lines.push('');\n lines.push('These items have low confidence and may need human review:');\n lines.push('');\n for (const req of result.analysis.disputes) {\n lines.push(`- **${req.requirement.id}:** ${req.requirement.description} (${req.confidence}% confidence)`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n// Verify command - Quick check for CI/CD\nasync function runVerify(args: string[]): Promise<void> {\n const options = parseOptions(args);\n\n // Check for API key\n if (!process.env.ANTHROPIC_API_KEY) {\n error('ANTHROPIC_API_KEY environment variable is required');\n process.exit(1);\n }\n\n const { quickVerify } = await import('./analyze/index.js');\n const exitCode = await quickVerify(options.path, {\n ci: true,\n verbose: options.verbose,\n });\n\n process.exit(exitCode);\n}\n\n// Discover command - Discovery only, no verification\nasync function runDiscover(args: string[]): Promise<void> {\n const options = parseOptions(args);\n\n const { analyze } = await import('./analyze/index.js');\n const result = await analyze(options.path, {\n output: options.output,\n ci: options.ci,\n verbose: options.verbose,\n discoveryOnly: true,\n });\n\n if (!result.success) {\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Traceability Commands\n// ============================================================================\n\n// Regressions command - Detect removed requirements\nasync function runRegressions(args: string[]): Promise<void> {\n const options = parseOptions(args);\n const projectRoot = resolve(options.path);\n\n const { detectRegressionsTool } = await import('./tools/detect-regressions.js');\n\n if (!options.ci) {\n console.log('\\n\\x1b[1mDetecting Regressions...\\x1b[0m\\n');\n }\n\n try {\n const result = await detectRegressionsTool.handler(\n {\n projectRoot,\n criticalOnly: options.ci, // In CI mode, only check critical\n failOnRegressions: options.ci,\n },\n { valid: true, scopes: ['tools:detect_regressions'] }\n );\n\n const content = result.content[0];\n if (content && 'text' in content) {\n console.log(content.text);\n }\n\n if (result.isError && options.ci) {\n process.exit(1);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n\n// Sprint Report command - Generate sprint scope change report\nasync function runSprintReport(args: string[]): Promise<void> {\n const options = parseOptions(args);\n const projectRoot = resolve(options.path);\n\n // Parse date arguments\n let sprintStart: string | undefined;\n let sprintEnd: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--start' && args[i + 1]) {\n sprintStart = args[++i];\n } else if (args[i] === '--end' && args[i + 1]) {\n sprintEnd = args[++i];\n }\n }\n\n const { generateSprintReportTool } = await import('./tools/generate-sprint-report.js');\n\n if (!options.ci) {\n console.log('\\n\\x1b[1mGenerating Sprint Report...\\x1b[0m\\n');\n }\n\n try {\n const result = await generateSprintReportTool.handler(\n {\n projectRoot,\n sprintStart,\n sprintEnd,\n },\n { valid: true, scopes: ['tools:generate_sprint_report'] }\n );\n\n const content = result.content[0];\n if (content && 'text' in content) {\n console.log(content.text);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n\n// Estimates command - Track estimate changes\nasync function runEstimates(args: string[]): Promise<void> {\n const options = parseOptions(args);\n const projectRoot = resolve(options.path);\n\n const { trackEstimatesTool } = await import('./tools/track-estimates.js');\n\n if (!options.ci) {\n console.log('\\n\\x1b[1mTracking Estimates...\\x1b[0m\\n');\n }\n\n try {\n const result = await trackEstimatesTool.handler(\n {\n projectRoot,\n },\n { valid: true, scopes: ['tools:track_estimates'] }\n );\n\n const content = result.content[0];\n if (content && 'text' in content) {\n console.log(content.text);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n\n// Audit command - Query audit trail\nasync function runAudit(args: string[]): Promise<void> {\n const options = parseOptions(args);\n const projectRoot = resolve(options.path);\n\n // Parse audit-specific arguments\n let limit = 50;\n let documentType: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--limit' && args[i + 1]) {\n limit = parseInt(args[++i] ?? '50', 10);\n } else if (args[i] === '--type' && args[i + 1]) {\n documentType = args[++i];\n }\n }\n\n const { getAuditTrailTool } = await import('./tools/get-audit-trail.js');\n\n if (!options.ci) {\n console.log('\\n\\x1b[1mQuerying Audit Trail...\\x1b[0m\\n');\n }\n\n try {\n const result = await getAuditTrailTool.handler(\n {\n projectRoot,\n limit,\n documentType,\n outputFormat: options.format === 'json' ? 'json' : 'markdown',\n },\n { valid: true, scopes: ['tools:get_audit_trail'] }\n );\n\n const content = result.content[0];\n if (content && 'text' in content) {\n console.log(content.text);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Setup Commands\n// ============================================================================\n\n// Init command - Interactive setup wizard\nasync function runInit(): Promise<void> {\n console.log(BANNER);\n console.log('\\x1b[1mVasperaPM Setup Wizard\\x1b[0m\\n');\n\n // Check for existing config\n const configPath = join(process.cwd(), '.vaspera.json');\n if (existsSync(configPath)) {\n warn('VasperaPM is already initialized in this project.');\n const answer = await prompt('Reinitialize? (y/N): ');\n if (answer.toLowerCase() !== 'y') {\n info('Setup cancelled.');\n return;\n }\n }\n\n // Mode selection\n console.log('\\n\\x1b[1m1. Select Mode\\x1b[0m\\n');\n console.log(' [1] Local mode (uses your Anthropic API key, no account needed)');\n console.log(' [2] Cloud mode (team features, dashboard, integrations)\\n');\n\n const modeAnswer = await prompt('Select mode (1 or 2): ');\n const mode = modeAnswer === '2' ? 'cloud' : 'local';\n\n // API key check\n console.log('\\n\\x1b[1m2. API Key\\x1b[0m\\n');\n\n let anthropicKey = process.env.ANTHROPIC_API_KEY || '';\n if (!anthropicKey) {\n console.log('VasperaPM requires an Anthropic API key for AI analysis.');\n console.log('Get one at: \\x1b[36mhttps://console.anthropic.com\\x1b[0m\\n');\n anthropicKey = await prompt('Enter your Anthropic API key (or press Enter to skip): ');\n } else {\n const masked = anthropicKey.substring(0, 10) + '...' + anthropicKey.substring(anthropicKey.length - 4);\n success(`Found API key: ${masked}`);\n }\n\n // Output directory\n console.log('\\n\\x1b[1m3. Output Directory\\x1b[0m\\n');\n\n const hasDocsDir = existsSync(join(process.cwd(), 'docs'));\n const defaultOutput = hasDocsDir ? 'docs/vasperaPM' : 'vasperaPM_Docs';\n console.log(`Default output: \\x1b[36m${defaultOutput}\\x1b[0m\\n`);\n\n const outputAnswer = await prompt(`Output directory (press Enter for ${defaultOutput}): `);\n const outputDir = outputAnswer || defaultOutput;\n\n // Create config\n const config = {\n version: '2.0',\n mode,\n output: {\n directory: outputDir,\n versioning: 'semantic',\n },\n discovery: {\n include: ['**/*.md', '**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.py'],\n exclude: ['node_modules', 'dist', '.git', 'coverage'],\n },\n verification: {\n strictness: 'standard',\n driftThreshold: 0.8,\n },\n };\n\n writeJsonFile(configPath, config);\n\n // Create .mcp.json if it doesn't exist\n const mcpConfigPath = join(process.cwd(), '.mcp.json');\n if (!existsSync(mcpConfigPath)) {\n const mcpConfig = {\n mcpServers: {\n 'vaspera-pm': {\n command: 'npx',\n args: ['vaspera-pm@latest', 'serve'],\n env: {\n ANTHROPIC_API_KEY: '${ANTHROPIC_API_KEY}',\n },\n },\n },\n };\n writeJsonFile(mcpConfigPath, mcpConfig);\n success('Created .mcp.json for Claude Code integration');\n }\n\n // Summary\n console.log('\\n');\n success('VasperaPM initialized successfully!');\n console.log('\\n\\x1b[1mConfiguration saved to:\\x1b[0m .vaspera.json');\n console.log('\\n\\x1b[1mNext steps:\\x1b[0m');\n\n if (!anthropicKey) {\n console.log(' 1. Set your Anthropic API key:');\n console.log(' \\x1b[36mexport ANTHROPIC_API_KEY=sk-ant-xxx\\x1b[0m\\n');\n console.log(' 2. Run your first analysis:');\n } else {\n console.log(' 1. Run your first analysis:');\n }\n\n console.log(' \\x1b[36mvaspera-pm analyze .\\x1b[0m\\n');\n console.log(' Output will be saved to: \\x1b[36m' + outputDir + '\\x1b[0m\\n');\n}\n\n// Main CLI\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const command = args[0]?.toLowerCase();\n const commandArgs = args.slice(1);\n\n switch (command) {\n case 'analyze':\n await runAnalyze(commandArgs);\n break;\n case 'verify':\n await runVerify(commandArgs);\n break;\n case 'discover':\n await runDiscover(commandArgs);\n break;\n case 'regressions':\n await runRegressions(commandArgs);\n break;\n case 'sprint-report':\n await runSprintReport(commandArgs);\n break;\n case 'estimates':\n await runEstimates(commandArgs);\n break;\n case 'audit':\n await runAudit(commandArgs);\n break;\n case 'init':\n await runInit();\n break;\n case 'install':\n await install();\n break;\n case 'connect':\n await connect();\n break;\n case 'serve':\n await serve();\n break;\n case 'status':\n await status();\n break;\n case 'help':\n case '--help':\n case '-h':\n console.log(BANNER);\n console.log(HELP);\n break;\n case '--version':\n case '-v':\n console.log(`vaspera-pm v${VERSION}`);\n break;\n case undefined:\n console.log(BANNER);\n console.log(HELP);\n break;\n default:\n error(`Unknown command: ${command}`);\n console.log(HELP);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n error(err.message);\n if (process.env.DEBUG) {\n console.error(err);\n }\n process.exit(1);\n});\n"],"mappings":"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","names":["randomBytes","error","error","init_types","error","resolve","DEFAULT_MODEL","init_types","dirname","status","status","existsSync","mkdirSync","readFileSync","writeFileSync","readdirSync","statSync","join","stats","existsSync","mkdirSync","readFileSync","join","createHash","writeFileSync","join","init_types","VERSION","init_types","VERSION","init_types","VERSION","init_types","VERSION","init_types","init_types","validation","error","validation","error","validation","error","existsSync","readFileSync","readdirSync","statSync","join","error","existsSync","readFileSync","readdirSync","statSync","join","relative","resolve","error","validation","error","validation","error","generateCSV","process","PRIORITY_MAP","generateCSV","init_sync_to_tracker","error","validation","error","validation","error","validation","error","validation","error","init_types","path","extractorInstance","path","init_types","existsSync","readFileSync","statSync","readdirSync","resolve","relative","extname","join","error","validation","error","existsSync","readFileSync","readdirSync","statSync","join","extname","relative","resolve","path","result","totalTokens","defaults","saved","error","validation","error","validation","error","success","init_types","init_types","error","existsSync","readdirSync","readFileSync","statSync","join","extname","relative","basename","createHash","error","error","init_types","createHash","writeFileSync","readFileSync","existsSync","mkdirSync","join","init_types","validation","init_types","createHash","error","init_types","promisify","init_types","status","init_types","result","path","init_types","init_types","init_types","init_types","status","init_types","stats","init_types","validation","error","createHash","error","code","init_types","error","validation","init_types","existsSync","resolve","error","init_types","status","init_types","stats","error","existsSync","resolve","path","error","existsSync","readFileSync","readdirSync","statSync","join","resolve","extname","error","path","prompt","output","error","existsSync","readFileSync","readdirSync","statSync","join","resolve","relative","error","getCategoryIcon","getPriorityIcon","PRIORITY_ICONS","groupByCategory","error","init_types","validation","error","status","path","resolve","init_types","validation","error","init_sync_to_tracker","VERSION","validation","success","error","existsSync","readdirSync","readFileSync","statSync","join","extname","relative","basename","DEFAULT_OPTIONS","EXCLUDE_PATHS","CODE_EXTENSIONS","resolve","writeFileSync","existsSync","discoveryDir","mkdirSync","discoveryReport","discoveryPath","existsSync","readFileSync","writeFileSync","mkdirSync","homedir","join","resolve","VERSION","path","startServer","analyze","runAgentVerification","detectOutputPath","jsonResult","summary","quickVerify","detectRegressionsTool","generateSprintReportTool","trackEstimatesTool","getAuditTrailTool"]}
|