@rag-forge/cli 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/logger.ts","../src/commands/index.ts","../src/lib/python-bridge.ts","../src/commands/audit.ts","../src/commands/query.ts","../src/commands/serve.ts","../src/commands/drift.ts","../src/commands/cost.ts","../src/commands/golden.ts","../src/commands/assess.ts","../src/commands/guardrails.ts","../src/commands/report.ts","../src/commands/cache.ts","../src/commands/inspect.ts","../src/commands/add.ts","../src/commands/parse.ts","../src/commands/chunk.ts","../src/commands/n8n.ts"],"sourcesContent":["import { Command } from \"commander\";\r\nimport { registerInitCommand } from \"./commands/init.js\";\r\nimport { registerIndexCommand } from \"./commands/index.js\";\r\nimport { registerAuditCommand } from \"./commands/audit.js\";\r\nimport { registerQueryCommand } from \"./commands/query.js\";\r\nimport { registerServeCommand } from \"./commands/serve.js\";\r\nimport { registerDriftCommand } from \"./commands/drift.js\";\r\nimport { registerCostCommand } from \"./commands/cost.js\";\r\nimport { registerGoldenCommand } from \"./commands/golden.js\";\r\nimport { registerAssessCommand } from \"./commands/assess.js\";\r\nimport { registerGuardrailsCommand } from \"./commands/guardrails.js\";\r\nimport { registerReportCommand } from \"./commands/report.js\";\r\nimport { registerCacheCommand } from \"./commands/cache.js\";\r\nimport { registerInspectCommand } from \"./commands/inspect.js\";\r\nimport { registerAddCommand } from \"./commands/add.js\";\r\nimport { registerParseCommand } from \"./commands/parse.js\";\r\nimport { registerChunkCommand } from \"./commands/chunk.js\";\r\nimport { registerN8nCommand } from \"./commands/n8n.js\";\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"rag-forge\")\r\n .description(\r\n \"Framework-agnostic CLI toolkit for production-grade RAG pipelines with evaluation baked in\",\r\n )\r\n .version(\"0.1.0\");\r\n\r\nregisterInitCommand(program);\r\nregisterIndexCommand(program);\r\nregisterAuditCommand(program);\r\nregisterQueryCommand(program);\r\nregisterServeCommand(program);\r\nregisterDriftCommand(program);\r\nregisterCostCommand(program);\r\nregisterGoldenCommand(program);\r\nregisterAssessCommand(program);\r\nregisterGuardrailsCommand(program);\r\nregisterReportCommand(program);\r\nregisterCacheCommand(program);\r\nregisterInspectCommand(program);\r\nregisterAddCommand(program);\r\nregisterParseCommand(program);\r\nregisterChunkCommand(program);\r\nregisterN8nCommand(program);\r\n\r\nprogram.parse();\r\n","import { existsSync } from \"node:fs\";\r\nimport { cp, readFile, writeFile, readdir } from \"node:fs/promises\";\r\nimport { dirname, join, resolve } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport type { Command } from \"commander\";\r\nimport { logger } from \"../lib/logger.js\";\r\nimport type { TemplateType } from \"../types/index.js\";\r\n\r\nconst AVAILABLE_TEMPLATES: TemplateType[] = [\"basic\", \"hybrid\", \"agentic\", \"enterprise\", \"n8n\"];\r\n\r\nfunction getTemplatesDir(): string {\r\n const currentDir = dirname(fileURLToPath(import.meta.url));\r\n // dist/index.js lives at packages/cli/dist/\r\n // three levels up reaches the monorepo root where templates/ lives\r\n return resolve(currentDir, \"..\", \"..\", \"..\", \"templates\");\r\n}\r\n\r\nasync function listFiles(dir: string, prefix = \"\"): Promise<string[]> {\r\n const entries = await readdir(dir, { withFileTypes: true });\r\n const files: string[] = [];\r\n for (const entry of entries) {\r\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\r\n if (entry.isDirectory()) {\r\n files.push(...(await listFiles(join(dir, entry.name), rel)));\r\n } else {\r\n files.push(rel);\r\n }\r\n }\r\n return files;\r\n}\r\n\r\nexport function registerInitCommand(program: Command): void {\r\n program\r\n .command(\"init\")\r\n .argument(\"[template]\", \"Project template to use\", \"basic\")\r\n .option(\"-d, --directory <dir>\", \"Target directory\")\r\n .option(\"--no-install\", \"Skip dependency installation\")\r\n .description(\"Scaffold a new RAG project from a template\")\r\n .action(async (template: string, options: { directory?: string; install: boolean }) => {\r\n const templateName = template as TemplateType;\r\n\r\n if (!AVAILABLE_TEMPLATES.includes(templateName)) {\r\n logger.error(\r\n `Unknown template \"${template}\". Available: ${AVAILABLE_TEMPLATES.join(\", \")}`,\r\n );\r\n process.exit(1);\r\n }\r\n\r\n const targetDir = resolve(options.directory ?? templateName);\r\n\r\n if (existsSync(targetDir) && options.directory !== \".\") {\r\n const entries = await readdir(targetDir);\r\n if (entries.length > 0) {\r\n logger.error(`Directory \"${targetDir}\" already exists and is not empty.`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const templatesDir = getTemplatesDir();\r\n const sourceDir = join(templatesDir, templateName, \"project\");\r\n\r\n if (!existsSync(sourceDir)) {\r\n logger.error(`Template \"${templateName}\" not found at ${sourceDir}`);\r\n process.exit(1);\r\n }\r\n\r\n logger.info(`Scaffolding ${templateName} RAG project in ${targetDir}...`);\r\n\r\n await cp(sourceDir, targetDir, { recursive: true });\r\n\r\n const projectName = targetDir.split(/[/\\\\]/).pop() ?? templateName;\r\n const pyprojectPath = join(targetDir, \"pyproject.toml\");\r\n if (existsSync(pyprojectPath)) {\r\n let content = await readFile(pyprojectPath, \"utf-8\");\r\n content = content.replace(/my-rag-pipeline/g, projectName);\r\n await writeFile(pyprojectPath, content, \"utf-8\");\r\n }\r\n\r\n const files = await listFiles(targetDir);\r\n for (const file of files) {\r\n logger.success(` Created ${file}`);\r\n }\r\n\r\n logger.info(\"\");\r\n logger.info(\"Next steps:\");\r\n logger.info(` cd ${targetDir}`);\r\n logger.info(\" rag-forge index --source ./docs\");\r\n logger.info(\" rag-forge audit --golden-set eval/golden_set.json\");\r\n });\r\n}\r\n","import chalk from \"chalk\";\n\nexport const logger = {\n info(message: string): void {\n console.log(chalk.blue(\"ℹ\"), message);\n },\n\n success(message: string): void {\n console.log(chalk.green(\"✓\"), message);\n },\n\n warn(message: string): void {\n console.log(chalk.yellow(\"⚠\"), message);\n },\n\n error(message: string): void {\n console.error(chalk.red(\"✗\"), message);\n },\n\n debug(message: string): void {\n if (process.env[\"DEBUG\"]) {\n console.log(chalk.gray(\"⊡\"), message);\n }\n },\n};\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface IndexResult {\r\n success: boolean;\r\n documents_processed: number;\r\n chunks_created: number;\r\n chunks_indexed: number;\r\n enrichment_summaries: number;\r\n errors: string[];\r\n}\r\n\r\nexport function registerIndexCommand(program: Command): void {\r\n program\r\n .command(\"index\")\r\n .requiredOption(\"-s, --source <dir>\", \"Source directory of documents to index\")\r\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\r\n .option(\"-e, --embedding <provider>\", \"Embedding provider: openai | local | mock\", \"mock\")\r\n .option(\"--strategy <name>\", \"Chunking strategy: fixed | recursive | semantic | structural | llm-driven\", \"recursive\")\r\n .option(\r\n \"--chunking-generator <provider>\",\r\n \"Generator for LLM-driven chunking: claude | openai | mock\",\r\n )\r\n .option(\"--enrich\", \"Enable contextual enrichment (document summary prepending)\")\r\n .option(\r\n \"--sparse-index-path <path>\",\r\n \"Path to persist BM25 sparse index\",\r\n )\r\n .option(\r\n \"--enrichment-generator <provider>\",\r\n \"Generator for enrichment summaries: claude | openai | mock\",\r\n )\r\n .description(\"Index documents into the vector store\")\r\n .action(\r\n async (options: {\r\n source: string;\r\n collection: string;\r\n embedding: string;\r\n strategy: string;\r\n chunkingGenerator?: string;\r\n enrich?: boolean;\r\n sparseIndexPath?: string;\r\n enrichmentGenerator?: string;\r\n }) => {\r\n const spinner = ora(\"Indexing documents...\").start();\r\n\r\n try {\r\n const configJson = JSON.stringify({\r\n embedding_provider: options.embedding,\r\n collection_name: options.collection,\r\n chunk_size: 512,\r\n overlap_ratio: 0.1,\r\n });\r\n\r\n const args = [\r\n \"index\",\r\n \"--source\",\r\n options.source,\r\n \"--collection\",\r\n options.collection,\r\n \"--embedding\",\r\n options.embedding,\r\n \"--config-json\",\r\n configJson,\r\n ];\r\n\r\n args.push(\"--strategy\", options.strategy);\r\n\r\n if (options.strategy === \"llm-driven\" && !options.chunkingGenerator) {\r\n spinner.fail(\"--chunking-generator is required for llm-driven strategy\");\r\n process.exit(1);\r\n }\r\n\r\n if (options.chunkingGenerator) {\r\n args.push(\"--chunking-generator\", options.chunkingGenerator);\r\n }\r\n\r\n if (options.enrichmentGenerator && !options.enrich) {\r\n spinner.fail(\"--enrichment-generator requires --enrich\");\r\n process.exit(1);\r\n }\r\n\r\n if (options.enrich) {\r\n args.push(\"--enrich\");\r\n }\r\n if (options.sparseIndexPath) {\r\n args.push(\"--sparse-index-path\", options.sparseIndexPath);\r\n }\r\n if (options.enrichmentGenerator) {\r\n args.push(\"--enrichment-generator\", options.enrichmentGenerator);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Indexing failed\");\r\n logger.error(result.stderr || \"Unknown error during indexing\");\r\n process.exit(1);\r\n }\r\n\r\n const output: IndexResult = JSON.parse(result.stdout);\r\n\r\n if (output.success) {\r\n spinner.succeed(\"Indexing complete\");\r\n logger.info(`Documents processed: ${String(output.documents_processed)}`);\r\n logger.info(`Chunks created: ${String(output.chunks_created)}`);\r\n logger.info(`Chunks indexed: ${String(output.chunks_indexed)}`);\r\n if (output.enrichment_summaries > 0) {\r\n logger.info(\r\n `Documents enriched: ${String(output.enrichment_summaries)}`,\r\n );\r\n }\r\n } else {\r\n spinner.warn(\"Indexing completed with errors\");\r\n for (const error of output.errors) {\r\n logger.error(error);\r\n }\r\n process.exit(1);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Indexing failed\");\r\n const message = error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","export {\r\n runPythonModule,\r\n checkPythonAvailable,\r\n} from \"@rag-forge/shared\";\r\nexport type {\r\n PythonBridgeOptions,\r\n PythonBridgeResult,\r\n} from \"@rag-forge/shared\";\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface AuditMetric {\r\n name: string;\r\n score: number;\r\n threshold: number;\r\n passed: boolean;\r\n}\r\n\r\ninterface AuditResult {\r\n success: boolean;\r\n overall_score: number;\r\n passed: boolean;\r\n rmm_level: number;\r\n rmm_name: string;\r\n samples_evaluated: number;\r\n metrics: AuditMetric[];\r\n report_path: string;\r\n json_report_path: string;\r\n evaluator_engine: string;\r\n pdf_report_path: string | null;\r\n}\r\n\r\nexport function registerAuditCommand(program: Command): void {\r\n program\r\n .command(\"audit\")\r\n .option(\"-i, --input <file>\", \"Path to telemetry JSONL file\")\r\n .option(\"-g, --golden-set <file>\", \"Path to golden set JSON file\")\r\n .option(\"-j, --judge <model>\", \"Judge model: mock | claude | openai\", \"mock\")\r\n .option(\"-o, --output <dir>\", \"Output directory for reports\", \"./reports\")\r\n .option(\"--evaluator <engine>\", \"Evaluator engine: llm-judge | ragas | deepeval\", \"llm-judge\")\r\n .option(\"--pdf\", \"Generate PDF report (requires Playwright)\")\r\n .description(\"Run evaluation on pipeline telemetry and generate audit report\")\r\n .action(\r\n async (options: {\r\n input?: string;\r\n goldenSet?: string;\r\n judge: string;\r\n output: string;\r\n evaluator: string;\r\n pdf?: boolean;\r\n }) => {\r\n if (!options.input && !options.goldenSet) {\r\n logger.error(\"Either --input or --golden-set is required\");\r\n process.exit(1);\r\n }\r\n\r\n const spinner = ora(\"Running RAG pipeline audit...\").start();\r\n\r\n try {\r\n const args = [\"audit\", \"--judge\", options.judge, \"--output\", options.output, \"--evaluator\", options.evaluator];\r\n\r\n if (options.input) {\r\n args.push(\"--input\", options.input);\r\n }\r\n if (options.goldenSet) {\r\n args.push(\"--golden-set\", options.goldenSet);\r\n }\r\n if (options.pdf) {\r\n args.push(\"--pdf\");\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Audit failed\");\r\n logger.error(result.stderr || \"Unknown error during audit\");\r\n process.exit(1);\r\n }\r\n\r\n const output: AuditResult = JSON.parse(result.stdout);\r\n\r\n if (output.passed) {\r\n spinner.succeed(\r\n `Audit passed — RMM-${String(output.rmm_level)}: ${output.rmm_name}`,\r\n );\r\n } else {\r\n spinner.warn(\r\n `Audit completed — RMM-${String(output.rmm_level)}: ${output.rmm_name}`,\r\n );\r\n }\r\n\r\n logger.info(`Overall score: ${output.overall_score.toFixed(2)}`);\r\n logger.info(`Samples evaluated: ${String(output.samples_evaluated)}`);\r\n\r\n for (const metric of output.metrics) {\r\n const status = metric.passed ? \"PASS\" : \"FAIL\";\r\n logger.info(\r\n ` ${metric.name}: ${metric.score.toFixed(2)} (threshold: ${metric.threshold.toFixed(2)}) [${status}]`,\r\n );\r\n }\r\n\r\n logger.info(`Evaluator: ${output.evaluator_engine}`);\r\n logger.success(`Report saved to: ${output.report_path}`);\r\n if (output.pdf_report_path) {\r\n logger.success(`PDF report: ${output.pdf_report_path}`);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Audit failed\");\r\n const message = error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface QuerySource {\r\n text: string;\r\n score: number;\r\n id: string;\r\n source_document?: string;\r\n}\r\n\r\ninterface QueryResult {\r\n answer: string;\r\n model_used: string;\r\n chunks_retrieved: number;\r\n sources: QuerySource[];\r\n blocked: boolean;\r\n blocked_reason: string | null;\r\n}\r\n\r\nexport function registerQueryCommand(program: Command): void {\r\n program\r\n .command(\"query\")\r\n .argument(\"<question>\", \"The question to ask the RAG pipeline\")\r\n .option(\"-k, --top-k <number>\", \"Number of chunks to retrieve\", \"5\")\r\n .option(\"-e, --embedding <provider>\", \"Embedding provider: openai | local | mock\", \"mock\")\r\n .option(\"-g, --generator <provider>\", \"Generation provider: claude | openai | mock\", \"mock\")\r\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\r\n .option(\r\n \"--strategy <type>\",\r\n \"Retrieval strategy: dense | sparse | hybrid\",\r\n \"dense\",\r\n )\r\n .option(\r\n \"--alpha <number>\",\r\n \"RRF alpha weighting for hybrid retrieval (0.0-1.0)\",\r\n \"0.6\",\r\n )\r\n .option(\r\n \"--reranker <type>\",\r\n \"Reranker: none | cohere | bge-local\",\r\n \"none\",\r\n )\r\n .option(\r\n \"--sparse-index-path <path>\",\r\n \"Path to BM25 sparse index\",\r\n )\r\n .option(\"--input-guard\", \"Enable input security guard\")\r\n .option(\"--output-guard\", \"Enable output security guard\")\r\n .option(\r\n \"--faithfulness-threshold <number>\",\r\n \"Faithfulness score threshold (0.0-1.0)\",\r\n \"0.85\",\r\n )\r\n .option(\"--rate-limit <number>\", \"Max queries per minute\", \"60\")\r\n .option(\"--cache\", \"Enable semantic query caching\")\r\n .option(\"--cache-ttl <seconds>\", \"Cache TTL in seconds\", \"3600\")\r\n .option(\"--cache-similarity <threshold>\", \"Cosine similarity threshold\", \"0.95\")\r\n .option(\"--agent-mode\", \"Enable multi-query decomposition\")\r\n .description(\"Execute a RAG query against the indexed pipeline\")\r\n .action(\r\n async (\r\n question: string,\r\n options: {\r\n topK: string;\r\n embedding: string;\r\n generator: string;\r\n collection: string;\r\n strategy: string;\r\n alpha: string;\r\n reranker: string;\r\n sparseIndexPath?: string;\r\n inputGuard?: boolean;\r\n outputGuard?: boolean;\r\n faithfulnessThreshold: string;\r\n rateLimit: string;\r\n cache?: boolean;\r\n cacheTtl: string;\r\n cacheSimilarity: string;\r\n agentMode?: boolean;\r\n },\r\n ) => {\r\n const spinner = ora(\"Querying pipeline...\").start();\r\n\r\n try {\r\n const args = [\r\n \"query\",\r\n \"--question\",\r\n question,\r\n \"--embedding\",\r\n options.embedding,\r\n \"--generator\",\r\n options.generator,\r\n \"--collection\",\r\n options.collection,\r\n \"--top-k\",\r\n options.topK,\r\n \"--strategy\",\r\n options.strategy,\r\n \"--alpha\",\r\n options.alpha,\r\n \"--reranker\",\r\n options.reranker,\r\n ];\r\n\r\n if (options.sparseIndexPath) {\r\n args.push(\"--sparse-index-path\", options.sparseIndexPath);\r\n }\r\n if (options.inputGuard) {\r\n args.push(\"--input-guard\");\r\n }\r\n if (options.outputGuard) {\r\n args.push(\"--output-guard\");\r\n }\r\n args.push(\"--faithfulness-threshold\", options.faithfulnessThreshold);\r\n args.push(\"--rate-limit\", options.rateLimit);\r\n if (options.cache) {\r\n args.push(\"--cache\");\r\n }\r\n args.push(\"--cache-ttl\", options.cacheTtl);\r\n args.push(\"--cache-similarity\", options.cacheSimilarity);\r\n if (options.agentMode) {\r\n args.push(\"--agent-mode\");\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Query failed\");\r\n logger.error(result.stderr || \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const output: QueryResult = JSON.parse(result.stdout);\r\n\r\n if (output.blocked) {\r\n spinner.warn(`Query blocked: ${output.blocked_reason ?? \"Unknown reason\"}`);\r\n return;\r\n }\r\n\r\n spinner.succeed(`Answer (${output.model_used}):`);\r\n\r\n\r\n console.log(\"\");\r\n console.log(output.answer);\r\n console.log(\"\");\r\n\r\n if (output.sources.length > 0) {\r\n logger.info(`Sources (${String(output.chunks_retrieved)} chunks):`);\r\n for (const source of output.sources) {\r\n logger.info(\r\n ` [${source.score.toFixed(3)}] ${source.text.slice(0, 120)}...`,\r\n );\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Query failed\");\r\n const message = error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import { spawn } from \"node:child_process\";\r\nimport { existsSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport type { Command } from \"commander\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\nfunction getMcpMainPath(): string {\r\n const currentDir = fileURLToPath(new URL(\".\", import.meta.url));\r\n return resolve(currentDir, \"..\", \"..\", \"..\", \"mcp\", \"dist\", \"main.js\");\r\n}\r\n\r\nexport function registerServeCommand(program: Command): void {\r\n program\r\n .command(\"serve\")\r\n .option(\"--mcp\", \"Launch MCP server\")\r\n .option(\"--transport <type>\", \"Transport: stdio | http\", \"stdio\")\r\n .option(\"-p, --port <number>\", \"Port for HTTP transport\", \"3100\")\r\n .description(\"Start the RAG-Forge server\")\r\n .action(async (options: { mcp?: boolean; transport: string; port: string }) => {\r\n if (!options.mcp) {\r\n logger.error(\"Please specify a server mode. Currently supported: --mcp\");\r\n process.exit(1);\r\n }\r\n\r\n const mcpMain = getMcpMainPath();\r\n\r\n if (!existsSync(mcpMain)) {\r\n logger.error(`MCP server not found at ${mcpMain}. Run 'pnpm run build' first.`);\r\n process.exit(1);\r\n }\r\n\r\n const args = [mcpMain];\r\n if (options.transport === \"http\") {\r\n args.push(\"--transport\", \"http\", \"--port\", options.port);\r\n logger.info(`Starting MCP server on http://localhost:${options.port}/sse`);\r\n } else {\r\n logger.info(\"Starting MCP server on stdio...\");\r\n }\r\n\r\n const child = spawn(process.execPath, args, {\r\n stdio: \"inherit\",\r\n });\r\n\r\n child.on(\"error\", (error) => {\r\n logger.error(`MCP server failed: ${error.message}`);\r\n process.exit(1);\r\n });\r\n\r\n child.on(\"exit\", (code) => {\r\n process.exit(code ?? 0);\r\n });\r\n });\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface DriftResult {\r\n success: boolean;\r\n is_drifting?: boolean;\r\n distance?: number;\r\n threshold?: number;\r\n details?: string;\r\n error?: string;\r\n baseline_path?: string;\r\n vectors_saved?: number;\r\n}\r\n\r\nexport function registerDriftCommand(program: Command): void {\r\n const drift = program\r\n .command(\"drift\")\r\n .description(\"Query drift detection and baseline management\");\r\n\r\n drift\r\n .command(\"report\")\r\n .requiredOption(\"--current <file>\", \"Path to current embeddings JSON\")\r\n .requiredOption(\"--baseline <file>\", \"Path to baseline embeddings JSON\")\r\n .option(\"--threshold <number>\", \"Drift threshold (cosine distance)\", \"0.15\")\r\n .description(\"Analyze query distribution drift from baseline\")\r\n .action(\r\n async (options: {\r\n current: string;\r\n baseline: string;\r\n threshold: string;\r\n }) => {\r\n const spinner = ora(\"Analyzing query drift...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_observability.cli\",\r\n args: [\r\n \"drift-report\",\r\n \"--current\",\r\n options.current,\r\n \"--baseline\",\r\n options.baseline,\r\n \"--threshold\",\r\n options.threshold,\r\n ],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Drift analysis failed\");\r\n logger.error(result.stderr || \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const output: DriftResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Drift analysis failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n if (output.is_drifting) {\r\n spinner.warn(\r\n `DRIFT DETECTED — distance: ${output.distance?.toFixed(4)} (threshold: ${output.threshold?.toFixed(4)})`,\r\n );\r\n } else {\r\n spinner.succeed(\r\n `No drift — distance: ${output.distance?.toFixed(4)} (threshold: ${output.threshold?.toFixed(4)})`,\r\n );\r\n }\r\n\r\n if (output.details) {\r\n logger.info(output.details);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Drift analysis failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n\r\n drift\r\n .command(\"save-baseline\")\r\n .requiredOption(\"--embeddings <file>\", \"Path to embeddings JSON\")\r\n .requiredOption(\"--output <file>\", \"Path to save baseline\")\r\n .description(\"Save current embeddings as drift baseline\")\r\n .action(async (options: { embeddings: string; output: string }) => {\r\n const spinner = ora(\"Saving drift baseline...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_observability.cli\",\r\n args: [\r\n \"drift-save-baseline\",\r\n \"--embeddings\",\r\n options.embeddings,\r\n \"--output\",\r\n options.output,\r\n ],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Failed to save baseline\");\r\n logger.error(result.stderr || \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const output: DriftResult = JSON.parse(result.stdout);\r\n\r\n if (output.success) {\r\n spinner.succeed(\r\n `Baseline saved: ${String(output.vectors_saved)} vectors → ${output.baseline_path}`,\r\n );\r\n } else {\r\n spinner.fail(\"Failed to save baseline\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Failed to save baseline\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface CostBreakdown {\r\n model: string;\r\n input_tokens_per_query: number;\r\n output_tokens_per_query: number;\r\n cost_per_query: number;\r\n}\r\n\r\ninterface CostResult {\r\n success: boolean;\r\n daily_cost: number;\r\n monthly_cost: number;\r\n queries_per_day: number;\r\n breakdown: CostBreakdown[];\r\n error?: string;\r\n}\r\n\r\nexport function registerCostCommand(program: Command): void {\r\n program\r\n .command(\"cost\")\r\n .requiredOption(\"--telemetry <file>\", \"Path to telemetry JSON file\")\r\n .option(\r\n \"--queries-per-day <number>\",\r\n \"Projected daily query volume (overrides telemetry file)\",\r\n )\r\n .description(\"Estimate monthly pipeline costs from telemetry\")\r\n .action(\r\n async (options: {\r\n telemetry: string;\r\n queriesPerDay?: string;\r\n }) => {\r\n const spinner = ora(\"Estimating costs...\").start();\r\n\r\n try {\r\n const args = [\"cost\", \"--telemetry\", options.telemetry];\r\n if (options.queriesPerDay) {\r\n args.push(\"--queries-per-day\", options.queriesPerDay);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<CostResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout is not JSON — use stderr\r\n }\r\n spinner.fail(\"Cost estimation failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: CostResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Cost estimation failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\"Cost estimation complete\");\r\n logger.info(\r\n `Daily cost: $${output.daily_cost.toFixed(4)} (${String(output.queries_per_day)} queries/day)`,\r\n );\r\n logger.info(`Monthly cost: $${output.monthly_cost.toFixed(2)}`);\r\n\r\n if (output.breakdown.length > 0) {\r\n logger.info(\"Breakdown by model:\");\r\n for (const item of output.breakdown) {\r\n logger.info(\r\n ` ${item.model}: $${item.cost_per_query.toFixed(6)}/query`,\r\n );\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Cost estimation failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface GoldenAddResult {\r\n success: boolean;\r\n added: number;\r\n total: number;\r\n golden_set_path: string;\r\n source: string;\r\n error?: string;\r\n}\r\n\r\ninterface GoldenValidateResult {\r\n success: boolean;\r\n valid: boolean;\r\n total_entries: number;\r\n errors: string[];\r\n error?: string;\r\n}\r\n\r\nexport function registerGoldenCommand(program: Command): void {\r\n const golden = program\r\n .command(\"golden\")\r\n .description(\"Golden set management for evaluation\");\r\n\r\n golden\r\n .command(\"add\")\r\n .requiredOption(\"-g, --golden-set <file>\", \"Path to golden set JSON\", \"eval/golden_set.json\")\r\n .option(\"--from-traffic <file>\", \"Sample from telemetry JSONL file\")\r\n .option(\"--sample-size <number>\", \"Number of entries to sample\", \"10\")\r\n .option(\"--query <question>\", \"Question to add manually\")\r\n .option(\"--keywords <list>\", \"Comma-separated expected keywords\")\r\n .option(\"--difficulty <level>\", \"Difficulty: easy | medium | hard\", \"medium\")\r\n .option(\"--topic <name>\", \"Topic category\", \"general\")\r\n .description(\"Add entries to the golden set (manual or from traffic)\")\r\n .action(\r\n async (options: {\r\n goldenSet: string;\r\n fromTraffic?: string;\r\n sampleSize: string;\r\n query?: string;\r\n keywords?: string;\r\n difficulty: string;\r\n topic: string;\r\n }) => {\r\n const spinner = ora(\"Adding to golden set...\").start();\r\n\r\n try {\r\n const args = [\r\n \"golden-add\",\r\n \"--golden-set\",\r\n options.goldenSet,\r\n ];\r\n\r\n if (options.fromTraffic) {\r\n args.push(\"--from-traffic\", options.fromTraffic);\r\n args.push(\"--sample-size\", options.sampleSize);\r\n } else if (options.query && options.keywords) {\r\n args.push(\"--query\", options.query);\r\n args.push(\"--keywords\", options.keywords);\r\n args.push(\"--difficulty\", options.difficulty);\r\n args.push(\"--topic\", options.topic);\r\n } else {\r\n spinner.fail(\"Provide --from-traffic <file> or --query <q> --keywords <k>\");\r\n process.exit(1);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<GoldenAddResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout is not JSON — use stderr\r\n }\r\n spinner.fail(\"Failed to add to golden set\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: GoldenAddResult = JSON.parse(result.stdout);\r\n\r\n if (output.success) {\r\n spinner.succeed(\r\n `Added ${String(output.added)} entries (total: ${String(output.total)}) → ${output.golden_set_path}`,\r\n );\r\n } else {\r\n spinner.fail(\"Failed to add to golden set\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Failed to add to golden set\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n\r\n golden\r\n .command(\"validate\")\r\n .requiredOption(\"-g, --golden-set <file>\", \"Path to golden set JSON\", \"eval/golden_set.json\")\r\n .description(\"Validate golden set coverage, balance, and schema\")\r\n .action(\r\n async (options: { goldenSet: string }) => {\r\n const spinner = ora(\"Validating golden set...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args: [\"golden-validate\", \"--golden-set\", options.goldenSet],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<GoldenValidateResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout is not JSON — use stderr\r\n }\r\n spinner.fail(\"Validation failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: GoldenValidateResult = JSON.parse(result.stdout);\r\n\r\n if (output.valid) {\r\n spinner.succeed(\r\n `Golden set valid — ${String(output.total_entries)} entries, no issues`,\r\n );\r\n } else {\r\n spinner.warn(\r\n `Golden set has ${String(output.errors.length)} issue(s):`,\r\n );\r\n for (const err of output.errors) {\r\n logger.warn(` - ${err}`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Validation failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface AssessCriteria {\r\n level: number;\r\n name: string;\r\n passed: boolean;\r\n checks: { description: string; passed: boolean; source: string }[];\r\n}\r\n\r\ninterface AssessResult {\r\n success: boolean;\r\n rmm_level: number;\r\n rmm_name: string;\r\n badge: string;\r\n criteria: AssessCriteria[];\r\n error?: string;\r\n}\r\n\r\nexport function registerAssessCommand(program: Command): void {\r\n program\r\n .command(\"assess\")\r\n .option(\"--config <json>\", \"Pipeline config as JSON string\")\r\n .option(\"--audit-report <file>\", \"Path to latest audit JSON report\")\r\n .description(\"Run RAG Maturity Model assessment\")\r\n .action(\r\n async (options: {\r\n config?: string;\r\n auditReport?: string;\r\n }) => {\r\n const spinner = ora(\"Running RMM assessment...\").start();\r\n\r\n try {\r\n const args = [\"assess\"];\r\n if (options.config) {\r\n args.push(\"--config-json\", options.config);\r\n }\r\n if (options.auditReport) {\r\n args.push(\"--audit-report\", options.auditReport);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<AssessResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout not JSON\r\n }\r\n spinner.fail(\"Assessment failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: AssessResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Assessment failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(output.badge);\r\n\r\n for (const criteria of output.criteria) {\r\n const icon = criteria.passed ? \"PASS\" : \"----\";\r\n logger.info(` [${icon}] RMM-${String(criteria.level)}: ${criteria.name}`);\r\n for (const check of criteria.checks) {\r\n const checkIcon = check.passed ? \"+\" : \"-\";\r\n const source = check.source !== \"config\" ? ` (${check.source})` : \"\";\r\n logger.info(` [${checkIcon}] ${check.description}${source}`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Assessment failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface GuardrailsTestResult {\r\n success: boolean;\r\n total_tested: number;\r\n blocked: number;\r\n passed_through: number;\r\n pass_rate: number;\r\n by_category: Record<string, { tested: number; blocked: number; pass_rate: number }>;\r\n failures: { text: string; category: string; severity: string }[];\r\n error?: string;\r\n}\r\n\r\ninterface PIIScanResult {\r\n success: boolean;\r\n chunks_scanned: number;\r\n chunks_with_pii: number;\r\n pii_types: Record<string, number>;\r\n affected_chunks: string[];\r\n error?: string;\r\n}\r\n\r\nexport function registerGuardrailsCommand(program: Command): void {\r\n const guardrails = program\r\n .command(\"guardrails\")\r\n .description(\"Security testing and PII scanning\");\r\n\r\n guardrails\r\n .command(\"test\")\r\n .option(\"--corpus <file>\", \"Path to custom adversarial corpus JSON\")\r\n .description(\"Run adversarial prompt test suite against security guards\")\r\n .action(\r\n async (options: { corpus?: string }) => {\r\n const spinner = ora(\"Running adversarial tests...\").start();\r\n\r\n try {\r\n const args = [\"guardrails-test\"];\r\n if (options.corpus) {\r\n args.push(\"--corpus\", options.corpus);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<GuardrailsTestResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout not JSON\r\n }\r\n spinner.fail(\"Adversarial tests failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: GuardrailsTestResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Adversarial tests failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const passPercent = (output.pass_rate * 100).toFixed(1);\r\n if (output.failures.length === 0) {\r\n spinner.succeed(\r\n `All attacks blocked — ${String(output.blocked)}/${String(output.total_tested)} (${passPercent}% block rate)`,\r\n );\r\n } else {\r\n spinner.warn(\r\n `${String(output.failures.length)} attacks got through — ${String(output.blocked)}/${String(output.total_tested)} blocked (${passPercent}% block rate)`,\r\n );\r\n }\r\n\r\n logger.info(\"By category:\");\r\n for (const [cat, stats] of Object.entries(output.by_category)) {\r\n const rate = (stats.pass_rate * 100).toFixed(0);\r\n logger.info(` ${cat}: ${String(stats.blocked)}/${String(stats.tested)} blocked (${rate}%)`);\r\n }\r\n\r\n if (output.failures.length > 0) {\r\n logger.warn(\"Failures (attacks that got through):\");\r\n for (const failure of output.failures) {\r\n logger.warn(` [${failure.severity}] ${failure.category}: ${failure.text.slice(0, 80)}...`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Adversarial tests failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n\r\n guardrails\r\n .command(\"scan-pii\")\r\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\r\n .description(\"Scan vector store for PII leakage\")\r\n .action(\r\n async (options: { collection: string }) => {\r\n const spinner = ora(\"Scanning for PII...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args: [\"guardrails-scan-pii\", \"--collection\", options.collection],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<PIIScanResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout not JSON\r\n }\r\n spinner.fail(\"PII scan failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: PIIScanResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"PII scan failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n if (output.chunks_with_pii === 0) {\r\n spinner.succeed(\r\n `No PII found — ${String(output.chunks_scanned)} chunks scanned`,\r\n );\r\n } else {\r\n spinner.warn(\r\n `PII found in ${String(output.chunks_with_pii)}/${String(output.chunks_scanned)} chunks`,\r\n );\r\n logger.warn(\"PII types detected:\");\r\n for (const [piiType, count] of Object.entries(output.pii_types)) {\r\n logger.warn(` ${piiType}: ${String(count)} occurrences`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"PII scan failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface ReportResult {\r\n success: boolean;\r\n report_path?: string;\r\n chunk_count?: number;\r\n has_audit?: boolean;\r\n drift_baseline?: boolean;\r\n error?: string;\r\n}\r\n\r\nexport function registerReportCommand(program: Command): void {\r\n program\r\n .command(\"report\")\r\n .option(\"-o, --output <dir>\", \"Output directory for reports\", \"./reports\")\r\n .option(\"--collection <name>\", \"Collection name\", \"rag-forge\")\r\n .description(\"Generate a pipeline health report dashboard\")\r\n .action(\r\n async (options: { output: string; collection: string }) => {\r\n const spinner = ora(\"Generating health report...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_evaluator.cli\",\r\n args: [\r\n \"report\",\r\n \"--output\",\r\n options.output,\r\n \"--collection\",\r\n options.collection,\r\n ],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<ReportResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout is not JSON — use stderr\r\n }\r\n spinner.fail(\"Report generation failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: ReportResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Report generation failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\"Health report generated\");\r\n logger.info(\r\n `Indexed chunks: ${String(output.chunk_count ?? 0)}`,\r\n );\r\n logger.info(\r\n `Audit data: ${output.has_audit ? \"included\" : \"none available\"}`,\r\n );\r\n logger.info(\r\n `Drift baseline: ${output.drift_baseline ? \"configured\" : \"not configured\"}`,\r\n );\r\n logger.success(`Report saved to: ${output.report_path ?? \"unknown\"}`);\r\n } catch (error) {\r\n spinner.fail(\"Report generation failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface CacheStatsResult {\r\n success: boolean;\r\n hits?: number;\r\n misses?: number;\r\n total?: number;\r\n hit_rate?: number;\r\n source?: string;\r\n message?: string;\r\n error?: string;\r\n}\r\n\r\nexport function registerCacheCommand(program: Command): void {\r\n const cache = program\r\n .command(\"cache\")\r\n .description(\"Semantic cache management\");\r\n\r\n cache\r\n .command(\"stats\")\r\n .description(\"Show semantic cache hit/miss statistics\")\r\n .action(async () => {\r\n const spinner = ora(\"Fetching cache statistics...\").start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args: [\"cache-stats\"],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(\r\n result.stdout,\r\n ) as Partial<CacheStatsResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout is not JSON — use stderr\r\n }\r\n spinner.fail(\"Failed to fetch cache stats\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: CacheStatsResult = JSON.parse(result.stdout);\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Failed to fetch cache stats\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\"Cache statistics\");\r\n\r\n const hitRate = output.hit_rate ?? 0;\r\n const hitRatePercent = (hitRate * 100).toFixed(1);\r\n\r\n logger.info(`Hit rate: ${hitRatePercent}%`);\r\n logger.info(`Hits: ${String(output.hits ?? 0)}`);\r\n logger.info(`Misses: ${String(output.misses ?? 0)}`);\r\n logger.info(`Total: ${String(output.total ?? 0)}`);\r\n logger.info(`Source: ${output.source ?? \"unknown\"}`);\r\n\r\n if (output.message) {\r\n logger.info(output.message);\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Failed to fetch cache stats\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface InspectResult {\r\n found: boolean;\r\n chunk_id: string;\r\n collection: string;\r\n text?: string;\r\n metadata?: Record<string, unknown>;\r\n error?: string;\r\n}\r\n\r\nexport function registerInspectCommand(program: Command): void {\r\n program\r\n .command(\"inspect\")\r\n .requiredOption(\"--chunk-id <id>\", \"The chunk ID to inspect\")\r\n .option(\"--collection <name>\", \"Collection name\", \"rag-forge\")\r\n .description(\"Inspect a specific chunk by ID\")\r\n .action(\r\n async (options: { chunkId: string; collection: string }) => {\r\n const spinner = ora(\r\n `Inspecting chunk ${options.chunkId}...`,\r\n ).start();\r\n\r\n try {\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args: [\r\n \"inspect\",\r\n \"--chunk-id\",\r\n options.chunkId,\r\n \"--collection\",\r\n options.collection,\r\n ],\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"Inspection failed\");\r\n logger.error(result.stderr || \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const output: InspectResult = JSON.parse(result.stdout);\r\n\r\n if (!output.found) {\r\n spinner.warn(\r\n `Chunk not found: ${options.chunkId} in collection ${output.collection}`,\r\n );\r\n if (output.error) {\r\n logger.error(output.error);\r\n }\r\n return;\r\n }\r\n\r\n spinner.succeed(`Chunk found: ${output.chunk_id}`);\r\n logger.info(`Collection: ${output.collection}`);\r\n\r\n if (output.text !== undefined) {\r\n logger.info(\"Text:\");\r\n logger.info(` ${output.text}`);\r\n }\r\n\r\n if (output.metadata) {\r\n logger.info(\"Metadata:\");\r\n for (const [key, value] of Object.entries(output.metadata)) {\r\n logger.info(` ${key}: ${String(value)}`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Inspection failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import { existsSync, readFileSync } from \"node:fs\";\r\nimport { cp, mkdir } from \"node:fs/promises\";\r\nimport { dirname, resolve } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport type { Command } from \"commander\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface ModuleFile {\r\n src: string;\r\n dest: string;\r\n}\r\n\r\ninterface ModuleDefinition {\r\n description: string;\r\n files: ModuleFile[];\r\n dependencies: string[];\r\n}\r\n\r\ninterface ModuleManifest {\r\n modules: Record<string, ModuleDefinition>;\r\n}\r\n\r\nfunction getPackageRoot(): string {\r\n const currentDir = dirname(fileURLToPath(import.meta.url));\r\n // Works for both src/commands/*.ts (dev) and dist/*.js (production)\r\n // In dev: packages/cli/src/commands -> up 2 = packages/cli\r\n // In prod: packages/cli/dist -> up 1 = packages/cli\r\n // Use path segment check: if currentDir ends with \"commands\", we're in src/commands\r\n if (currentDir.endsWith(\"commands\") || currentDir.endsWith(\"commands\\\\\") || currentDir.endsWith(\"commands/\")) {\r\n return resolve(currentDir, \"..\", \"..\");\r\n }\r\n return resolve(currentDir, \"..\");\r\n}\r\n\r\nfunction getManifestPath(): string {\r\n return resolve(getPackageRoot(), \"src\", \"modules\", \"manifest.json\");\r\n}\r\n\r\nfunction getTemplateSourceDir(): string {\r\n // Monorepo templates: packages/cli -> up 2 = monorepo root -> templates/\r\n return resolve(getPackageRoot(), \"..\", \"..\", \"templates\", \"enterprise\", \"project\", \"src\");\r\n}\r\n\r\nexport function registerAddCommand(program: Command): void {\r\n program\r\n .command(\"add\")\r\n .argument(\r\n \"<module>\",\r\n \"Module to add: guardrails | caching | reranking | enrichment | observability | hybrid-retrieval\",\r\n )\r\n .description(\"Add a feature module as editable source code (shadcn/ui model)\")\r\n .action(async (moduleName: string) => {\r\n const manifestPath = getManifestPath();\r\n if (!existsSync(manifestPath)) {\r\n logger.error(`Module manifest not found at ${manifestPath}`);\r\n process.exit(1);\r\n }\r\n\r\n const manifest: ModuleManifest = JSON.parse(\r\n readFileSync(manifestPath, \"utf-8\"),\r\n ) as ModuleManifest;\r\n const mod = manifest.modules[moduleName];\r\n\r\n if (!mod) {\r\n const available = Object.keys(manifest.modules).join(\", \");\r\n logger.error(`Unknown module: ${moduleName}. Available: ${available}`);\r\n process.exit(1);\r\n }\r\n\r\n logger.info(`Adding module: ${moduleName} — ${mod.description}`);\r\n\r\n const sourceDir = getTemplateSourceDir();\r\n let added = 0;\r\n let skipped = 0;\r\n let missingSources = 0;\r\n\r\n for (const file of mod.files) {\r\n const srcPath = resolve(sourceDir, file.src);\r\n const destPath = resolve(process.cwd(), file.dest);\r\n\r\n if (existsSync(destPath)) {\r\n logger.warn(` Skip (exists): ${file.dest}`);\r\n skipped++;\r\n continue;\r\n }\r\n\r\n if (!existsSync(srcPath)) {\r\n logger.warn(` Skip (source not found): ${file.src}`);\r\n missingSources++;\r\n continue;\r\n }\r\n\r\n await mkdir(dirname(destPath), { recursive: true });\r\n await cp(srcPath, destPath);\r\n logger.success(` Added: ${file.dest}`);\r\n added++;\r\n }\r\n\r\n logger.info(\r\n `\\nAdded ${String(added)} files, skipped ${String(skipped)}, missing ${String(missingSources)}`,\r\n );\r\n\r\n // Fail if nothing was added due to missing sources — indicates packaging/manifest defect\r\n if (added === 0 && missingSources > 0) {\r\n logger.error(\r\n \"No files were added because all sources are missing. This indicates a packaging or manifest problem.\",\r\n );\r\n process.exit(1);\r\n }\r\n\r\n if (mod.dependencies.length > 0) {\r\n logger.info(\"\\nInstall dependencies:\");\r\n logger.info(` pip install ${mod.dependencies.join(\" \")}`);\r\n }\r\n });\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface FileInfo {\r\n path: string;\r\n characters: number;\r\n}\r\n\r\ninterface ParseResult {\r\n success: boolean;\r\n files_found: number;\r\n files: FileInfo[];\r\n total_characters: number;\r\n parse_errors: string[];\r\n error?: string;\r\n}\r\n\r\nexport function registerParseCommand(program: Command): void {\r\n program\r\n .command(\"parse\")\r\n .option(\"-s, --source <directory>\", \"Source directory to parse\", \"./docs\")\r\n .description(\"Preview document extraction without indexing\")\r\n .action(async (options: { source: string }) => {\r\n const spinner = ora(\"Parsing documents...\").start();\r\n\r\n try {\r\n const args = [\"parse\", \"--source\", options.source];\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<ParseResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout not JSON\r\n }\r\n spinner.fail(\"Parse preview failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: ParseResult = JSON.parse(result.stdout) as ParseResult;\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Parse preview failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\r\n `Found ${String(output.files_found)} files (${String(output.total_characters)} characters)`,\r\n );\r\n\r\n if (output.files.length > 0) {\r\n console.log(\"\");\r\n for (const file of output.files) {\r\n logger.info(` ${file.path} (${String(file.characters)} chars)`);\r\n }\r\n }\r\n\r\n if (output.parse_errors.length > 0) {\r\n console.log(\"\");\r\n logger.warn(`${String(output.parse_errors.length)} parse errors:`);\r\n for (const err of output.parse_errors) {\r\n logger.warn(` ${err}`);\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Parse preview failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface ChunkSample {\r\n index: number;\r\n source: string;\r\n preview: string;\r\n}\r\n\r\ninterface ChunkStats {\r\n avg_chunk_size: number;\r\n min_chunk_size: number;\r\n max_chunk_size: number;\r\n total_tokens: number;\r\n}\r\n\r\ninterface ChunkResult {\r\n success: boolean;\r\n strategy: string;\r\n chunk_size: number;\r\n total_chunks: number;\r\n stats: ChunkStats;\r\n samples: ChunkSample[];\r\n error?: string;\r\n}\r\n\r\nexport function registerChunkCommand(program: Command): void {\r\n program\r\n .command(\"chunk\")\r\n .option(\"-s, --source <directory>\", \"Source directory to chunk\", \"./docs\")\r\n .option(\r\n \"--strategy <type>\",\r\n \"Chunking strategy: fixed | recursive | semantic | structural | llm-driven\",\r\n \"recursive\",\r\n )\r\n .option(\"--chunk-size <tokens>\", \"Target chunk size in tokens\")\r\n .description(\"Preview chunking without indexing\")\r\n .action(\r\n async (options: {\r\n source: string;\r\n strategy: string;\r\n chunkSize?: string;\r\n }) => {\r\n const spinner = ora(\"Chunking documents...\").start();\r\n\r\n try {\r\n const args = [\r\n \"chunk\",\r\n \"--source\",\r\n options.source,\r\n \"--strategy\",\r\n options.strategy,\r\n ];\r\n\r\n if (options.chunkSize) {\r\n args.push(\"--chunk-size\", options.chunkSize);\r\n }\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n let errorMessage = result.stderr || \"Unknown error\";\r\n try {\r\n const parsed = JSON.parse(result.stdout) as Partial<ChunkResult>;\r\n if (parsed.error) errorMessage = parsed.error;\r\n } catch {\r\n // stdout not JSON\r\n }\r\n spinner.fail(\"Chunk preview failed\");\r\n logger.error(errorMessage);\r\n process.exit(1);\r\n }\r\n\r\n const output: ChunkResult = JSON.parse(\r\n result.stdout,\r\n ) as ChunkResult;\r\n\r\n if (!output.success) {\r\n spinner.fail(\"Chunk preview failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\r\n `${String(output.total_chunks)} chunks (${output.strategy}, target ${String(output.chunk_size)} tokens)`,\r\n );\r\n\r\n console.log(\"\");\r\n logger.info(\"Stats:\");\r\n logger.info(\r\n ` Avg size: ${String(output.stats.avg_chunk_size)} tokens`,\r\n );\r\n logger.info(\r\n ` Min size: ${String(output.stats.min_chunk_size)} tokens`,\r\n );\r\n logger.info(\r\n ` Max size: ${String(output.stats.max_chunk_size)} tokens`,\r\n );\r\n logger.info(\r\n ` Total tokens: ${String(output.stats.total_tokens)}`,\r\n );\r\n\r\n if (output.samples.length > 0) {\r\n console.log(\"\");\r\n logger.info(\"Sample chunks:\");\r\n for (const sample of output.samples) {\r\n logger.info(\r\n ` [${String(sample.index)}] ${sample.source}: ${sample.preview}`,\r\n );\r\n }\r\n }\r\n } catch (error) {\r\n spinner.fail(\"Chunk preview failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n },\r\n );\r\n}\r\n","import type { Command } from \"commander\";\r\nimport ora from \"ora\";\r\nimport { runPythonModule } from \"../lib/python-bridge.js\";\r\nimport { logger } from \"../lib/logger.js\";\r\n\r\ninterface N8nExportResult {\r\n success: boolean;\r\n output_path: string;\r\n nodes: number;\r\n error?: string;\r\n}\r\n\r\nexport function registerN8nCommand(program: Command): void {\r\n program\r\n .command(\"n8n\")\r\n .option(\r\n \"-o, --output <file>\",\r\n \"Output file path\",\r\n \"n8n-workflow.json\",\r\n )\r\n .option(\r\n \"--mcp-url <url>\",\r\n \"MCP server SSE endpoint\",\r\n \"http://localhost:3100/sse\",\r\n )\r\n .description(\"Export pipeline configuration as an importable n8n workflow\")\r\n .action(async (options: { output: string; mcpUrl: string }) => {\r\n const spinner = ora(\"Generating n8n workflow...\").start();\r\n\r\n try {\r\n const args = [\r\n \"n8n-export\",\r\n \"--output\",\r\n options.output,\r\n \"--mcp-url\",\r\n options.mcpUrl,\r\n ];\r\n\r\n const result = await runPythonModule({\r\n module: \"rag_forge_core.cli\",\r\n args,\r\n });\r\n\r\n if (result.exitCode !== 0) {\r\n spinner.fail(\"n8n export failed\");\r\n logger.error(result.stderr || \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n const output: N8nExportResult = JSON.parse(\r\n result.stdout,\r\n ) as N8nExportResult;\r\n\r\n if (!output.success) {\r\n spinner.fail(\"n8n export failed\");\r\n logger.error(output.error ?? \"Unknown error\");\r\n process.exit(1);\r\n }\r\n\r\n spinner.succeed(\r\n `Exported n8n workflow with ${String(output.nodes)} nodes`,\r\n );\r\n logger.info(` Output: ${output.output_path}`);\r\n logger.info(\"\");\r\n logger.info(\"Import this file into n8n via:\");\r\n logger.info(\" 1. Open n8n dashboard\");\r\n logger.info(\" 2. Click 'Import from File'\");\r\n logger.info(` 3. Select ${output.output_path}`);\r\n } catch (error) {\r\n spinner.fail(\"n8n export failed\");\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n logger.error(message);\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n"],"mappings":"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","names":["program","program","ora","program","ora","ora","program","ora","existsSync","resolve","fileURLToPath","fileURLToPath","resolve","program","existsSync","ora","program","ora","ora","program","ora","ora","program","ora","ora","program","ora","ora","program","ora","ora","program","ora","ora","program","ora","ora","program","ora","existsSync","cp","dirname","resolve","fileURLToPath","dirname","fileURLToPath","resolve","program","existsSync","cp","ora","program","ora","ora","program","ora","ora","program","ora"]}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@rag-forge/cli",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic CLI toolkit for production-grade RAG pipelines with evaluation baked in",
5
+ "author": "Femi Adedayo",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/hallengray/rag-forge.git",
9
+ "directory": "packages/cli"
10
+ },
11
+ "homepage": "https://github.com/hallengray/rag-forge#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/hallengray/rag-forge/issues"
14
+ },
15
+ "keywords": [
16
+ "rag",
17
+ "retrieval-augmented-generation",
18
+ "evaluation",
19
+ "llm",
20
+ "cli",
21
+ "rag-pipeline",
22
+ "ragas",
23
+ "deepeval"
24
+ ],
25
+ "type": "module",
26
+ "bin": {
27
+ "rag-forge": "./dist/index.js"
28
+ },
29
+ "exports": {
30
+ ".": {
31
+ "import": "./dist/index.js",
32
+ "types": "./dist/index.d.ts"
33
+ }
34
+ },
35
+ "files": ["dist", "src/modules"],
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "dev": "tsup --watch",
39
+ "lint": "eslint src/",
40
+ "lint:fix": "eslint src/ --fix",
41
+ "typecheck": "tsc --noEmit",
42
+ "test": "vitest run"
43
+ },
44
+ "dependencies": {
45
+ "@rag-forge/shared": "workspace:*",
46
+ "chalk": "^5.3.0",
47
+ "commander": "^12.0.0",
48
+ "cosmiconfig": "^9.0.0",
49
+ "ora": "^8.0.0",
50
+ "zod": "^3.23.0"
51
+ },
52
+ "devDependencies": {
53
+ "@eslint/js": "^9.0.0",
54
+ "@types/node": "^22.0.0",
55
+ "eslint": "^9.0.0",
56
+ "tsup": "^8.0.0",
57
+ "typescript": "^5.5.0",
58
+ "typescript-eslint": "^8.0.0",
59
+ "vitest": "^2.0.0"
60
+ },
61
+ "engines": {
62
+ "node": ">=20.0.0"
63
+ },
64
+ "license": "MIT"
65
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "modules": {
3
+ "guardrails": {
4
+ "description": "InputGuard + OutputGuard security pipeline",
5
+ "files": [
6
+ {"src": "security/input_guard.py", "dest": "src/security/input_guard.py"},
7
+ {"src": "security/output_guard.py", "dest": "src/security/output_guard.py"},
8
+ {"src": "security/injection.py", "dest": "src/security/injection.py"},
9
+ {"src": "security/pii.py", "dest": "src/security/pii.py"},
10
+ {"src": "security/faithfulness.py", "dest": "src/security/faithfulness.py"},
11
+ {"src": "security/citations.py", "dest": "src/security/citations.py"}
12
+ ],
13
+ "dependencies": ["presidio-analyzer>=2.2"]
14
+ },
15
+ "caching": {
16
+ "description": "Semantic query caching with Redis support",
17
+ "files": [
18
+ {"src": "context/semantic_cache.py", "dest": "src/caching/semantic_cache.py"},
19
+ {"src": "context/cache_store.py", "dest": "src/caching/cache_store.py"}
20
+ ],
21
+ "dependencies": ["redis>=5.0"]
22
+ },
23
+ "reranking": {
24
+ "description": "Cross-encoder reranking (Cohere + BGE local)",
25
+ "files": [
26
+ {"src": "retrieval/reranker.py", "dest": "src/retrieval/reranker.py"}
27
+ ],
28
+ "dependencies": ["cohere>=5.0"]
29
+ },
30
+ "enrichment": {
31
+ "description": "Contextual enrichment (document summary prepending)",
32
+ "files": [
33
+ {"src": "context/enricher.py", "dest": "src/enrichment/enricher.py"}
34
+ ],
35
+ "dependencies": []
36
+ },
37
+ "observability": {
38
+ "description": "OpenTelemetry tracing for all pipeline stages",
39
+ "files": [
40
+ {"src": "observability/tracing.py", "dest": "src/observability/tracing.py"}
41
+ ],
42
+ "dependencies": ["opentelemetry-api>=1.20", "opentelemetry-sdk>=1.20"]
43
+ },
44
+ "hybrid-retrieval": {
45
+ "description": "Hybrid dense+sparse retrieval with RRF fusion",
46
+ "files": [
47
+ {"src": "retrieval/sparse.py", "dest": "src/retrieval/sparse.py"},
48
+ {"src": "retrieval/hybrid.py", "dest": "src/retrieval/hybrid.py"}
49
+ ],
50
+ "dependencies": ["bm25s>=0.2"]
51
+ }
52
+ }
53
+ }