@rag-forge/cli 0.1.0 → 0.1.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Femi Adedayo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @rag-forge/cli
2
+
3
+ > Framework-agnostic CLI toolkit for production-grade RAG pipelines with evaluation baked in.
4
+
5
+ `rag-forge` is the command-line interface to RAG-Forge, a polyglot toolkit for building, evaluating, and auditing Retrieval-Augmented Generation pipelines. It scaffolds new projects, indexes documents, runs hybrid retrieval, scores pipeline output against the RAG Maturity Model (RMM), and ships every report as HTML, JSON, or PDF.
6
+
7
+ **Built for the moment your "demo works on my laptop" RAG meets a real production workload.**
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g @rag-forge/cli
13
+ # or
14
+ pnpm add -g @rag-forge/cli
15
+ ```
16
+
17
+ The CLI delegates pipeline and evaluation work to Python packages. Install them in a dedicated venv:
18
+
19
+ ```bash
20
+ mkdir -p ~/.rag-forge && cd ~/.rag-forge
21
+ uv venv && source .venv/bin/activate
22
+ uv pip install rag-forge-core rag-forge-evaluator rag-forge-observability
23
+ ```
24
+
25
+ Verify:
26
+
27
+ ```bash
28
+ rag-forge --version
29
+ rag-forge-eval --help
30
+ ```
31
+
32
+ ## Quick start
33
+
34
+ ```bash
35
+ # Scaffold a new RAG project
36
+ rag-forge init basic my-rag-project
37
+ cd my-rag-project
38
+
39
+ # Index your documents
40
+ rag-forge index --source ./docs
41
+
42
+ # Run an audit against a golden set
43
+ rag-forge audit --golden-set eval/golden_set.json --judge claude
44
+ ```
45
+
46
+ The audit command prints a pre-run banner with sample count, judge model, total judge calls, estimated time, and estimated USD cost — and asks for confirmation (auto-confirmed when invoked through the npm CLI). Per-sample progress streams to stderr as the run proceeds, and a summary line shows scored count, skipped count, RMM level, and report path on completion.
47
+
48
+ ## Core commands
49
+
50
+ | Command | What it does |
51
+ |---|---|
52
+ | `rag-forge init <template>` | Scaffold a new project from a template (basic, hybrid, agentic, enterprise, n8n) |
53
+ | `rag-forge index --source <dir>` | Chunk and embed a directory of documents into your vector store |
54
+ | `rag-forge query "<question>"` | Run a single RAG query end-to-end against the indexed corpus |
55
+ | `rag-forge audit` | Score pipeline output against metrics + the RAG Maturity Model |
56
+ | `rag-forge cost` | Estimate audit costs for any judge / evaluator combination |
57
+ | `rag-forge drift report` | Compare current run against a saved baseline |
58
+ | `rag-forge golden add` | Add entries to your golden question/answer set |
59
+ | `rag-forge guardrails test` | Run input/output guardrails against a test corpus |
60
+ | `rag-forge serve --mcp` | Start as an MCP server for Claude Desktop or any MCP client |
61
+ | `rag-forge inspect` | Inspect indexed chunks, embeddings, and retrieval results |
62
+
63
+ Run `rag-forge <command> --help` for full options on any command.
64
+
65
+ ## The RAG Maturity Model
66
+
67
+ RAG-Forge scores every audit against a 6-level maturity model (RMM-0 through RMM-5):
68
+
69
+ | Level | Theme | Exit criterion |
70
+ |---|---|---|
71
+ | **0 — Naive** | Vector search returns results | Basic retrieval works |
72
+ | **1 — Better Recall** | Hybrid search + RRF fusion | Recall@5 > 70% |
73
+ | **2 — Better Precision** | Cross-encoder reranking | nDCG@10 +10% |
74
+ | **3 — Better Trust** | Faithfulness, citations, guardrails | Faithfulness > 85% |
75
+ | **4 — Better Workflow** | Caching, cost tracking, P95 budgets | Cache hit rate, cost meter active |
76
+ | **5 — Enterprise** | Drift detection, CI/CD gates, adversarial tests | All audit thresholds pass |
77
+
78
+ The audit command tells you which level you're at and what specifically you need to do to move up.
79
+
80
+ ## Bring your own everything
81
+
82
+ - **LLM provider:** Anthropic, OpenAI, Gemini, Cohere, Bedrock, Ollama, vLLM, or any model behind your own gateway. The `JudgeProvider` protocol is two methods.
83
+ - **Vector store:** Qdrant, pgvector, Pinecone, Weaviate, Chroma, or any store implementing the `VectorStore` protocol.
84
+ - **Embedding model:** OpenAI, Cohere, sentence-transformers, BGE, or any model exposing an `embed_documents()` method.
85
+ - **Reranker:** Cohere, BGE, ColBERT, or skip reranking entirely.
86
+
87
+ Configure once in `rag-forge.config.ts` at your project root, then every command honors your choices.
88
+
89
+ ## Documentation
90
+
91
+ - **Full docs:** [github.com/hallengray/rag-forge](https://github.com/hallengray/rag-forge#readme)
92
+ - **Issues:** [github.com/hallengray/rag-forge/issues](https://github.com/hallengray/rag-forge/issues)
93
+ - **Release notes:** [docs/release-notes](https://github.com/hallengray/rag-forge/tree/main/docs/release-notes)
94
+
95
+ ## License
96
+
97
+ MIT — Femi Adedayo
package/dist/index.js CHANGED
@@ -196,7 +196,10 @@ function registerIndexCommand(program2) {
196
196
  // src/commands/audit.ts
197
197
  import ora2 from "ora";
198
198
  function registerAuditCommand(program2) {
199
- program2.command("audit").option("-i, --input <file>", "Path to telemetry JSONL file").option("-g, --golden-set <file>", "Path to golden set JSON file").option("-j, --judge <model>", "Judge model: mock | claude | openai", "mock").option("-o, --output <dir>", "Output directory for reports", "./reports").option("--evaluator <engine>", "Evaluator engine: llm-judge | ragas | deepeval", "llm-judge").option("--pdf", "Generate PDF report (requires Playwright)").description("Run evaluation on pipeline telemetry and generate audit report").action(
199
+ program2.command("audit").option("-i, --input <file>", "Path to telemetry JSONL file").option("-g, --golden-set <file>", "Path to golden set JSON file").option("-j, --judge <model>", "Judge provider: mock | claude | openai", "mock").option(
200
+ "--judge-model <name>",
201
+ "Specific judge model id (e.g. claude-opus-4-6, gpt-4-turbo). Falls back to RAG_FORGE_JUDGE_MODEL env var, then provider default."
202
+ ).option("-o, --output <dir>", "Output directory for reports", "./reports").option("--evaluator <engine>", "Evaluator engine: llm-judge | ragas | deepeval", "llm-judge").option("--pdf", "Generate PDF report (requires Playwright)").description("Run evaluation on pipeline telemetry and generate audit report").action(
200
203
  async (options) => {
201
204
  if (!options.input && !options.goldenSet) {
202
205
  logger.error("Either --input or --golden-set is required");
@@ -204,13 +207,25 @@ function registerAuditCommand(program2) {
204
207
  }
205
208
  const spinner = ora2("Running RAG pipeline audit...").start();
206
209
  try {
207
- const args = ["audit", "--judge", options.judge, "--output", options.output, "--evaluator", options.evaluator];
210
+ const args = [
211
+ "audit",
212
+ "--judge",
213
+ options.judge,
214
+ "--output",
215
+ options.output,
216
+ "--evaluator",
217
+ options.evaluator,
218
+ "--yes"
219
+ ];
208
220
  if (options.input) {
209
221
  args.push("--input", options.input);
210
222
  }
211
223
  if (options.goldenSet) {
212
224
  args.push("--golden-set", options.goldenSet);
213
225
  }
226
+ if (options.judgeModel) {
227
+ args.push("--judge-model", options.judgeModel);
228
+ }
214
229
  if (options.pdf) {
215
230
  args.push("--pdf");
216
231
  }
package/dist/index.js.map CHANGED
@@ -1 +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"]}
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\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerIndexCommand } from \"./commands/index.js\";\nimport { registerAuditCommand } from \"./commands/audit.js\";\nimport { registerQueryCommand } from \"./commands/query.js\";\nimport { registerServeCommand } from \"./commands/serve.js\";\nimport { registerDriftCommand } from \"./commands/drift.js\";\nimport { registerCostCommand } from \"./commands/cost.js\";\nimport { registerGoldenCommand } from \"./commands/golden.js\";\nimport { registerAssessCommand } from \"./commands/assess.js\";\nimport { registerGuardrailsCommand } from \"./commands/guardrails.js\";\nimport { registerReportCommand } from \"./commands/report.js\";\nimport { registerCacheCommand } from \"./commands/cache.js\";\nimport { registerInspectCommand } from \"./commands/inspect.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerParseCommand } from \"./commands/parse.js\";\nimport { registerChunkCommand } from \"./commands/chunk.js\";\nimport { registerN8nCommand } from \"./commands/n8n.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"rag-forge\")\n .description(\n \"Framework-agnostic CLI toolkit for production-grade RAG pipelines with evaluation baked in\",\n )\n .version(\"0.1.0\");\n\nregisterInitCommand(program);\nregisterIndexCommand(program);\nregisterAuditCommand(program);\nregisterQueryCommand(program);\nregisterServeCommand(program);\nregisterDriftCommand(program);\nregisterCostCommand(program);\nregisterGoldenCommand(program);\nregisterAssessCommand(program);\nregisterGuardrailsCommand(program);\nregisterReportCommand(program);\nregisterCacheCommand(program);\nregisterInspectCommand(program);\nregisterAddCommand(program);\nregisterParseCommand(program);\nregisterChunkCommand(program);\nregisterN8nCommand(program);\n\nprogram.parse();\n","import { existsSync } from \"node:fs\";\nimport { cp, readFile, writeFile, readdir } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Command } from \"commander\";\nimport { logger } from \"../lib/logger.js\";\nimport type { TemplateType } from \"../types/index.js\";\n\nconst AVAILABLE_TEMPLATES: TemplateType[] = [\"basic\", \"hybrid\", \"agentic\", \"enterprise\", \"n8n\"];\n\nfunction getTemplatesDir(): string {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n // dist/index.js lives at packages/cli/dist/\n // three levels up reaches the monorepo root where templates/ lives\n return resolve(currentDir, \"..\", \"..\", \"..\", \"templates\");\n}\n\nasync function listFiles(dir: string, prefix = \"\"): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n files.push(...(await listFiles(join(dir, entry.name), rel)));\n } else {\n files.push(rel);\n }\n }\n return files;\n}\n\nexport function registerInitCommand(program: Command): void {\n program\n .command(\"init\")\n .argument(\"[template]\", \"Project template to use\", \"basic\")\n .option(\"-d, --directory <dir>\", \"Target directory\")\n .option(\"--no-install\", \"Skip dependency installation\")\n .description(\"Scaffold a new RAG project from a template\")\n .action(async (template: string, options: { directory?: string; install: boolean }) => {\n const templateName = template as TemplateType;\n\n if (!AVAILABLE_TEMPLATES.includes(templateName)) {\n logger.error(\n `Unknown template \"${template}\". Available: ${AVAILABLE_TEMPLATES.join(\", \")}`,\n );\n process.exit(1);\n }\n\n const targetDir = resolve(options.directory ?? templateName);\n\n if (existsSync(targetDir) && options.directory !== \".\") {\n const entries = await readdir(targetDir);\n if (entries.length > 0) {\n logger.error(`Directory \"${targetDir}\" already exists and is not empty.`);\n process.exit(1);\n }\n }\n\n const templatesDir = getTemplatesDir();\n const sourceDir = join(templatesDir, templateName, \"project\");\n\n if (!existsSync(sourceDir)) {\n logger.error(`Template \"${templateName}\" not found at ${sourceDir}`);\n process.exit(1);\n }\n\n logger.info(`Scaffolding ${templateName} RAG project in ${targetDir}...`);\n\n await cp(sourceDir, targetDir, { recursive: true });\n\n const projectName = targetDir.split(/[/\\\\]/).pop() ?? templateName;\n const pyprojectPath = join(targetDir, \"pyproject.toml\");\n if (existsSync(pyprojectPath)) {\n let content = await readFile(pyprojectPath, \"utf-8\");\n content = content.replace(/my-rag-pipeline/g, projectName);\n await writeFile(pyprojectPath, content, \"utf-8\");\n }\n\n const files = await listFiles(targetDir);\n for (const file of files) {\n logger.success(` Created ${file}`);\n }\n\n logger.info(\"\");\n logger.info(\"Next steps:\");\n logger.info(` cd ${targetDir}`);\n logger.info(\" rag-forge index --source ./docs\");\n logger.info(\" rag-forge audit --golden-set eval/golden_set.json\");\n });\n}\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\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface IndexResult {\n success: boolean;\n documents_processed: number;\n chunks_created: number;\n chunks_indexed: number;\n enrichment_summaries: number;\n errors: string[];\n}\n\nexport function registerIndexCommand(program: Command): void {\n program\n .command(\"index\")\n .requiredOption(\"-s, --source <dir>\", \"Source directory of documents to index\")\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\n .option(\"-e, --embedding <provider>\", \"Embedding provider: openai | local | mock\", \"mock\")\n .option(\"--strategy <name>\", \"Chunking strategy: fixed | recursive | semantic | structural | llm-driven\", \"recursive\")\n .option(\n \"--chunking-generator <provider>\",\n \"Generator for LLM-driven chunking: claude | openai | mock\",\n )\n .option(\"--enrich\", \"Enable contextual enrichment (document summary prepending)\")\n .option(\n \"--sparse-index-path <path>\",\n \"Path to persist BM25 sparse index\",\n )\n .option(\n \"--enrichment-generator <provider>\",\n \"Generator for enrichment summaries: claude | openai | mock\",\n )\n .description(\"Index documents into the vector store\")\n .action(\n async (options: {\n source: string;\n collection: string;\n embedding: string;\n strategy: string;\n chunkingGenerator?: string;\n enrich?: boolean;\n sparseIndexPath?: string;\n enrichmentGenerator?: string;\n }) => {\n const spinner = ora(\"Indexing documents...\").start();\n\n try {\n const configJson = JSON.stringify({\n embedding_provider: options.embedding,\n collection_name: options.collection,\n chunk_size: 512,\n overlap_ratio: 0.1,\n });\n\n const args = [\n \"index\",\n \"--source\",\n options.source,\n \"--collection\",\n options.collection,\n \"--embedding\",\n options.embedding,\n \"--config-json\",\n configJson,\n ];\n\n args.push(\"--strategy\", options.strategy);\n\n if (options.strategy === \"llm-driven\" && !options.chunkingGenerator) {\n spinner.fail(\"--chunking-generator is required for llm-driven strategy\");\n process.exit(1);\n }\n\n if (options.chunkingGenerator) {\n args.push(\"--chunking-generator\", options.chunkingGenerator);\n }\n\n if (options.enrichmentGenerator && !options.enrich) {\n spinner.fail(\"--enrichment-generator requires --enrich\");\n process.exit(1);\n }\n\n if (options.enrich) {\n args.push(\"--enrich\");\n }\n if (options.sparseIndexPath) {\n args.push(\"--sparse-index-path\", options.sparseIndexPath);\n }\n if (options.enrichmentGenerator) {\n args.push(\"--enrichment-generator\", options.enrichmentGenerator);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Indexing failed\");\n logger.error(result.stderr || \"Unknown error during indexing\");\n process.exit(1);\n }\n\n const output: IndexResult = JSON.parse(result.stdout);\n\n if (output.success) {\n spinner.succeed(\"Indexing complete\");\n logger.info(`Documents processed: ${String(output.documents_processed)}`);\n logger.info(`Chunks created: ${String(output.chunks_created)}`);\n logger.info(`Chunks indexed: ${String(output.chunks_indexed)}`);\n if (output.enrichment_summaries > 0) {\n logger.info(\n `Documents enriched: ${String(output.enrichment_summaries)}`,\n );\n }\n } else {\n spinner.warn(\"Indexing completed with errors\");\n for (const error of output.errors) {\n logger.error(error);\n }\n process.exit(1);\n }\n } catch (error) {\n spinner.fail(\"Indexing failed\");\n const message = error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","export {\n runPythonModule,\n checkPythonAvailable,\n} from \"@rag-forge/shared\";\nexport type {\n PythonBridgeOptions,\n PythonBridgeResult,\n} from \"@rag-forge/shared\";\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface AuditMetric {\n name: string;\n score: number;\n threshold: number;\n passed: boolean;\n}\n\ninterface AuditResult {\n success: boolean;\n overall_score: number;\n passed: boolean;\n rmm_level: number;\n rmm_name: string;\n samples_evaluated: number;\n metrics: AuditMetric[];\n report_path: string;\n json_report_path: string;\n evaluator_engine: string;\n pdf_report_path: string | null;\n}\n\nexport function registerAuditCommand(program: Command): void {\n program\n .command(\"audit\")\n .option(\"-i, --input <file>\", \"Path to telemetry JSONL file\")\n .option(\"-g, --golden-set <file>\", \"Path to golden set JSON file\")\n .option(\"-j, --judge <model>\", \"Judge provider: mock | claude | openai\", \"mock\")\n .option(\n \"--judge-model <name>\",\n \"Specific judge model id (e.g. claude-opus-4-6, gpt-4-turbo). Falls back to RAG_FORGE_JUDGE_MODEL env var, then provider default.\",\n )\n .option(\"-o, --output <dir>\", \"Output directory for reports\", \"./reports\")\n .option(\"--evaluator <engine>\", \"Evaluator engine: llm-judge | ragas | deepeval\", \"llm-judge\")\n .option(\"--pdf\", \"Generate PDF report (requires Playwright)\")\n .description(\"Run evaluation on pipeline telemetry and generate audit report\")\n .action(\n async (options: {\n input?: string;\n goldenSet?: string;\n judge: string;\n judgeModel?: string;\n output: string;\n evaluator: string;\n pdf?: boolean;\n }) => {\n if (!options.input && !options.goldenSet) {\n logger.error(\"Either --input or --golden-set is required\");\n process.exit(1);\n }\n\n const spinner = ora(\"Running RAG pipeline audit...\").start();\n\n try {\n // The TS CLI invokes the Python evaluator via a non-TTY subprocess,\n // so we always forward --yes to suppress the Python-side confirmation\n // prompt. The TS layer is the user-facing entry point and is\n // responsible for any user interaction. v0.1.2 will add a TS-side\n // confirmation prompt before launching the subprocess.\n const args = [\n \"audit\",\n \"--judge\",\n options.judge,\n \"--output\",\n options.output,\n \"--evaluator\",\n options.evaluator,\n \"--yes\",\n ];\n\n if (options.input) {\n args.push(\"--input\", options.input);\n }\n if (options.goldenSet) {\n args.push(\"--golden-set\", options.goldenSet);\n }\n if (options.judgeModel) {\n args.push(\"--judge-model\", options.judgeModel);\n }\n if (options.pdf) {\n args.push(\"--pdf\");\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Audit failed\");\n logger.error(result.stderr || \"Unknown error during audit\");\n process.exit(1);\n }\n\n const output: AuditResult = JSON.parse(result.stdout);\n\n if (output.passed) {\n spinner.succeed(\n `Audit passed — RMM-${String(output.rmm_level)}: ${output.rmm_name}`,\n );\n } else {\n spinner.warn(\n `Audit completed — RMM-${String(output.rmm_level)}: ${output.rmm_name}`,\n );\n }\n\n logger.info(`Overall score: ${output.overall_score.toFixed(2)}`);\n logger.info(`Samples evaluated: ${String(output.samples_evaluated)}`);\n\n for (const metric of output.metrics) {\n const status = metric.passed ? \"PASS\" : \"FAIL\";\n logger.info(\n ` ${metric.name}: ${metric.score.toFixed(2)} (threshold: ${metric.threshold.toFixed(2)}) [${status}]`,\n );\n }\n\n logger.info(`Evaluator: ${output.evaluator_engine}`);\n logger.success(`Report saved to: ${output.report_path}`);\n if (output.pdf_report_path) {\n logger.success(`PDF report: ${output.pdf_report_path}`);\n }\n } catch (error) {\n spinner.fail(\"Audit failed\");\n const message = error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface QuerySource {\n text: string;\n score: number;\n id: string;\n source_document?: string;\n}\n\ninterface QueryResult {\n answer: string;\n model_used: string;\n chunks_retrieved: number;\n sources: QuerySource[];\n blocked: boolean;\n blocked_reason: string | null;\n}\n\nexport function registerQueryCommand(program: Command): void {\n program\n .command(\"query\")\n .argument(\"<question>\", \"The question to ask the RAG pipeline\")\n .option(\"-k, --top-k <number>\", \"Number of chunks to retrieve\", \"5\")\n .option(\"-e, --embedding <provider>\", \"Embedding provider: openai | local | mock\", \"mock\")\n .option(\"-g, --generator <provider>\", \"Generation provider: claude | openai | mock\", \"mock\")\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\n .option(\n \"--strategy <type>\",\n \"Retrieval strategy: dense | sparse | hybrid\",\n \"dense\",\n )\n .option(\n \"--alpha <number>\",\n \"RRF alpha weighting for hybrid retrieval (0.0-1.0)\",\n \"0.6\",\n )\n .option(\n \"--reranker <type>\",\n \"Reranker: none | cohere | bge-local\",\n \"none\",\n )\n .option(\n \"--sparse-index-path <path>\",\n \"Path to BM25 sparse index\",\n )\n .option(\"--input-guard\", \"Enable input security guard\")\n .option(\"--output-guard\", \"Enable output security guard\")\n .option(\n \"--faithfulness-threshold <number>\",\n \"Faithfulness score threshold (0.0-1.0)\",\n \"0.85\",\n )\n .option(\"--rate-limit <number>\", \"Max queries per minute\", \"60\")\n .option(\"--cache\", \"Enable semantic query caching\")\n .option(\"--cache-ttl <seconds>\", \"Cache TTL in seconds\", \"3600\")\n .option(\"--cache-similarity <threshold>\", \"Cosine similarity threshold\", \"0.95\")\n .option(\"--agent-mode\", \"Enable multi-query decomposition\")\n .description(\"Execute a RAG query against the indexed pipeline\")\n .action(\n async (\n question: string,\n options: {\n topK: string;\n embedding: string;\n generator: string;\n collection: string;\n strategy: string;\n alpha: string;\n reranker: string;\n sparseIndexPath?: string;\n inputGuard?: boolean;\n outputGuard?: boolean;\n faithfulnessThreshold: string;\n rateLimit: string;\n cache?: boolean;\n cacheTtl: string;\n cacheSimilarity: string;\n agentMode?: boolean;\n },\n ) => {\n const spinner = ora(\"Querying pipeline...\").start();\n\n try {\n const args = [\n \"query\",\n \"--question\",\n question,\n \"--embedding\",\n options.embedding,\n \"--generator\",\n options.generator,\n \"--collection\",\n options.collection,\n \"--top-k\",\n options.topK,\n \"--strategy\",\n options.strategy,\n \"--alpha\",\n options.alpha,\n \"--reranker\",\n options.reranker,\n ];\n\n if (options.sparseIndexPath) {\n args.push(\"--sparse-index-path\", options.sparseIndexPath);\n }\n if (options.inputGuard) {\n args.push(\"--input-guard\");\n }\n if (options.outputGuard) {\n args.push(\"--output-guard\");\n }\n args.push(\"--faithfulness-threshold\", options.faithfulnessThreshold);\n args.push(\"--rate-limit\", options.rateLimit);\n if (options.cache) {\n args.push(\"--cache\");\n }\n args.push(\"--cache-ttl\", options.cacheTtl);\n args.push(\"--cache-similarity\", options.cacheSimilarity);\n if (options.agentMode) {\n args.push(\"--agent-mode\");\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Query failed\");\n logger.error(result.stderr || \"Unknown error\");\n process.exit(1);\n }\n\n const output: QueryResult = JSON.parse(result.stdout);\n\n if (output.blocked) {\n spinner.warn(`Query blocked: ${output.blocked_reason ?? \"Unknown reason\"}`);\n return;\n }\n\n spinner.succeed(`Answer (${output.model_used}):`);\n\n\n console.log(\"\");\n console.log(output.answer);\n console.log(\"\");\n\n if (output.sources.length > 0) {\n logger.info(`Sources (${String(output.chunks_retrieved)} chunks):`);\n for (const source of output.sources) {\n logger.info(\n ` [${source.score.toFixed(3)}] ${source.text.slice(0, 120)}...`,\n );\n }\n }\n } catch (error) {\n spinner.fail(\"Query failed\");\n const message = error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Command } from \"commander\";\nimport { logger } from \"../lib/logger.js\";\n\nfunction getMcpMainPath(): string {\n const currentDir = fileURLToPath(new URL(\".\", import.meta.url));\n return resolve(currentDir, \"..\", \"..\", \"..\", \"mcp\", \"dist\", \"main.js\");\n}\n\nexport function registerServeCommand(program: Command): void {\n program\n .command(\"serve\")\n .option(\"--mcp\", \"Launch MCP server\")\n .option(\"--transport <type>\", \"Transport: stdio | http\", \"stdio\")\n .option(\"-p, --port <number>\", \"Port for HTTP transport\", \"3100\")\n .description(\"Start the RAG-Forge server\")\n .action(async (options: { mcp?: boolean; transport: string; port: string }) => {\n if (!options.mcp) {\n logger.error(\"Please specify a server mode. Currently supported: --mcp\");\n process.exit(1);\n }\n\n const mcpMain = getMcpMainPath();\n\n if (!existsSync(mcpMain)) {\n logger.error(`MCP server not found at ${mcpMain}. Run 'pnpm run build' first.`);\n process.exit(1);\n }\n\n const args = [mcpMain];\n if (options.transport === \"http\") {\n args.push(\"--transport\", \"http\", \"--port\", options.port);\n logger.info(`Starting MCP server on http://localhost:${options.port}/sse`);\n } else {\n logger.info(\"Starting MCP server on stdio...\");\n }\n\n const child = spawn(process.execPath, args, {\n stdio: \"inherit\",\n });\n\n child.on(\"error\", (error) => {\n logger.error(`MCP server failed: ${error.message}`);\n process.exit(1);\n });\n\n child.on(\"exit\", (code) => {\n process.exit(code ?? 0);\n });\n });\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface DriftResult {\n success: boolean;\n is_drifting?: boolean;\n distance?: number;\n threshold?: number;\n details?: string;\n error?: string;\n baseline_path?: string;\n vectors_saved?: number;\n}\n\nexport function registerDriftCommand(program: Command): void {\n const drift = program\n .command(\"drift\")\n .description(\"Query drift detection and baseline management\");\n\n drift\n .command(\"report\")\n .requiredOption(\"--current <file>\", \"Path to current embeddings JSON\")\n .requiredOption(\"--baseline <file>\", \"Path to baseline embeddings JSON\")\n .option(\"--threshold <number>\", \"Drift threshold (cosine distance)\", \"0.15\")\n .description(\"Analyze query distribution drift from baseline\")\n .action(\n async (options: {\n current: string;\n baseline: string;\n threshold: string;\n }) => {\n const spinner = ora(\"Analyzing query drift...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_observability.cli\",\n args: [\n \"drift-report\",\n \"--current\",\n options.current,\n \"--baseline\",\n options.baseline,\n \"--threshold\",\n options.threshold,\n ],\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Drift analysis failed\");\n logger.error(result.stderr || \"Unknown error\");\n process.exit(1);\n }\n\n const output: DriftResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Drift analysis failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n if (output.is_drifting) {\n spinner.warn(\n `DRIFT DETECTED — distance: ${output.distance?.toFixed(4)} (threshold: ${output.threshold?.toFixed(4)})`,\n );\n } else {\n spinner.succeed(\n `No drift — distance: ${output.distance?.toFixed(4)} (threshold: ${output.threshold?.toFixed(4)})`,\n );\n }\n\n if (output.details) {\n logger.info(output.details);\n }\n } catch (error) {\n spinner.fail(\"Drift analysis failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n\n drift\n .command(\"save-baseline\")\n .requiredOption(\"--embeddings <file>\", \"Path to embeddings JSON\")\n .requiredOption(\"--output <file>\", \"Path to save baseline\")\n .description(\"Save current embeddings as drift baseline\")\n .action(async (options: { embeddings: string; output: string }) => {\n const spinner = ora(\"Saving drift baseline...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_observability.cli\",\n args: [\n \"drift-save-baseline\",\n \"--embeddings\",\n options.embeddings,\n \"--output\",\n options.output,\n ],\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Failed to save baseline\");\n logger.error(result.stderr || \"Unknown error\");\n process.exit(1);\n }\n\n const output: DriftResult = JSON.parse(result.stdout);\n\n if (output.success) {\n spinner.succeed(\n `Baseline saved: ${String(output.vectors_saved)} vectors → ${output.baseline_path}`,\n );\n } else {\n spinner.fail(\"Failed to save baseline\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n } catch (error) {\n spinner.fail(\"Failed to save baseline\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface CostBreakdown {\n model: string;\n input_tokens_per_query: number;\n output_tokens_per_query: number;\n cost_per_query: number;\n}\n\ninterface CostResult {\n success: boolean;\n daily_cost: number;\n monthly_cost: number;\n queries_per_day: number;\n breakdown: CostBreakdown[];\n error?: string;\n}\n\nexport function registerCostCommand(program: Command): void {\n program\n .command(\"cost\")\n .requiredOption(\"--telemetry <file>\", \"Path to telemetry JSON file\")\n .option(\n \"--queries-per-day <number>\",\n \"Projected daily query volume (overrides telemetry file)\",\n )\n .description(\"Estimate monthly pipeline costs from telemetry\")\n .action(\n async (options: {\n telemetry: string;\n queriesPerDay?: string;\n }) => {\n const spinner = ora(\"Estimating costs...\").start();\n\n try {\n const args = [\"cost\", \"--telemetry\", options.telemetry];\n if (options.queriesPerDay) {\n args.push(\"--queries-per-day\", options.queriesPerDay);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<CostResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout is not JSON — use stderr\n }\n spinner.fail(\"Cost estimation failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: CostResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Cost estimation failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\"Cost estimation complete\");\n logger.info(\n `Daily cost: $${output.daily_cost.toFixed(4)} (${String(output.queries_per_day)} queries/day)`,\n );\n logger.info(`Monthly cost: $${output.monthly_cost.toFixed(2)}`);\n\n if (output.breakdown.length > 0) {\n logger.info(\"Breakdown by model:\");\n for (const item of output.breakdown) {\n logger.info(\n ` ${item.model}: $${item.cost_per_query.toFixed(6)}/query`,\n );\n }\n }\n } catch (error) {\n spinner.fail(\"Cost estimation failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface GoldenAddResult {\n success: boolean;\n added: number;\n total: number;\n golden_set_path: string;\n source: string;\n error?: string;\n}\n\ninterface GoldenValidateResult {\n success: boolean;\n valid: boolean;\n total_entries: number;\n errors: string[];\n error?: string;\n}\n\nexport function registerGoldenCommand(program: Command): void {\n const golden = program\n .command(\"golden\")\n .description(\"Golden set management for evaluation\");\n\n golden\n .command(\"add\")\n .requiredOption(\"-g, --golden-set <file>\", \"Path to golden set JSON\", \"eval/golden_set.json\")\n .option(\"--from-traffic <file>\", \"Sample from telemetry JSONL file\")\n .option(\"--sample-size <number>\", \"Number of entries to sample\", \"10\")\n .option(\"--query <question>\", \"Question to add manually\")\n .option(\"--keywords <list>\", \"Comma-separated expected keywords\")\n .option(\"--difficulty <level>\", \"Difficulty: easy | medium | hard\", \"medium\")\n .option(\"--topic <name>\", \"Topic category\", \"general\")\n .description(\"Add entries to the golden set (manual or from traffic)\")\n .action(\n async (options: {\n goldenSet: string;\n fromTraffic?: string;\n sampleSize: string;\n query?: string;\n keywords?: string;\n difficulty: string;\n topic: string;\n }) => {\n const spinner = ora(\"Adding to golden set...\").start();\n\n try {\n const args = [\n \"golden-add\",\n \"--golden-set\",\n options.goldenSet,\n ];\n\n if (options.fromTraffic) {\n args.push(\"--from-traffic\", options.fromTraffic);\n args.push(\"--sample-size\", options.sampleSize);\n } else if (options.query && options.keywords) {\n args.push(\"--query\", options.query);\n args.push(\"--keywords\", options.keywords);\n args.push(\"--difficulty\", options.difficulty);\n args.push(\"--topic\", options.topic);\n } else {\n spinner.fail(\"Provide --from-traffic <file> or --query <q> --keywords <k>\");\n process.exit(1);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<GoldenAddResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout is not JSON — use stderr\n }\n spinner.fail(\"Failed to add to golden set\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: GoldenAddResult = JSON.parse(result.stdout);\n\n if (output.success) {\n spinner.succeed(\n `Added ${String(output.added)} entries (total: ${String(output.total)}) → ${output.golden_set_path}`,\n );\n } else {\n spinner.fail(\"Failed to add to golden set\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n } catch (error) {\n spinner.fail(\"Failed to add to golden set\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n\n golden\n .command(\"validate\")\n .requiredOption(\"-g, --golden-set <file>\", \"Path to golden set JSON\", \"eval/golden_set.json\")\n .description(\"Validate golden set coverage, balance, and schema\")\n .action(\n async (options: { goldenSet: string }) => {\n const spinner = ora(\"Validating golden set...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args: [\"golden-validate\", \"--golden-set\", options.goldenSet],\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<GoldenValidateResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout is not JSON — use stderr\n }\n spinner.fail(\"Validation failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: GoldenValidateResult = JSON.parse(result.stdout);\n\n if (output.valid) {\n spinner.succeed(\n `Golden set valid — ${String(output.total_entries)} entries, no issues`,\n );\n } else {\n spinner.warn(\n `Golden set has ${String(output.errors.length)} issue(s):`,\n );\n for (const err of output.errors) {\n logger.warn(` - ${err}`);\n }\n }\n } catch (error) {\n spinner.fail(\"Validation failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface AssessCriteria {\n level: number;\n name: string;\n passed: boolean;\n checks: { description: string; passed: boolean; source: string }[];\n}\n\ninterface AssessResult {\n success: boolean;\n rmm_level: number;\n rmm_name: string;\n badge: string;\n criteria: AssessCriteria[];\n error?: string;\n}\n\nexport function registerAssessCommand(program: Command): void {\n program\n .command(\"assess\")\n .option(\"--config <json>\", \"Pipeline config as JSON string\")\n .option(\"--audit-report <file>\", \"Path to latest audit JSON report\")\n .description(\"Run RAG Maturity Model assessment\")\n .action(\n async (options: {\n config?: string;\n auditReport?: string;\n }) => {\n const spinner = ora(\"Running RMM assessment...\").start();\n\n try {\n const args = [\"assess\"];\n if (options.config) {\n args.push(\"--config-json\", options.config);\n }\n if (options.auditReport) {\n args.push(\"--audit-report\", options.auditReport);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<AssessResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout not JSON\n }\n spinner.fail(\"Assessment failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: AssessResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Assessment failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(output.badge);\n\n for (const criteria of output.criteria) {\n const icon = criteria.passed ? \"PASS\" : \"----\";\n logger.info(` [${icon}] RMM-${String(criteria.level)}: ${criteria.name}`);\n for (const check of criteria.checks) {\n const checkIcon = check.passed ? \"+\" : \"-\";\n const source = check.source !== \"config\" ? ` (${check.source})` : \"\";\n logger.info(` [${checkIcon}] ${check.description}${source}`);\n }\n }\n } catch (error) {\n spinner.fail(\"Assessment failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface GuardrailsTestResult {\n success: boolean;\n total_tested: number;\n blocked: number;\n passed_through: number;\n pass_rate: number;\n by_category: Record<string, { tested: number; blocked: number; pass_rate: number }>;\n failures: { text: string; category: string; severity: string }[];\n error?: string;\n}\n\ninterface PIIScanResult {\n success: boolean;\n chunks_scanned: number;\n chunks_with_pii: number;\n pii_types: Record<string, number>;\n affected_chunks: string[];\n error?: string;\n}\n\nexport function registerGuardrailsCommand(program: Command): void {\n const guardrails = program\n .command(\"guardrails\")\n .description(\"Security testing and PII scanning\");\n\n guardrails\n .command(\"test\")\n .option(\"--corpus <file>\", \"Path to custom adversarial corpus JSON\")\n .description(\"Run adversarial prompt test suite against security guards\")\n .action(\n async (options: { corpus?: string }) => {\n const spinner = ora(\"Running adversarial tests...\").start();\n\n try {\n const args = [\"guardrails-test\"];\n if (options.corpus) {\n args.push(\"--corpus\", options.corpus);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<GuardrailsTestResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout not JSON\n }\n spinner.fail(\"Adversarial tests failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: GuardrailsTestResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Adversarial tests failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n const passPercent = (output.pass_rate * 100).toFixed(1);\n if (output.failures.length === 0) {\n spinner.succeed(\n `All attacks blocked — ${String(output.blocked)}/${String(output.total_tested)} (${passPercent}% block rate)`,\n );\n } else {\n spinner.warn(\n `${String(output.failures.length)} attacks got through — ${String(output.blocked)}/${String(output.total_tested)} blocked (${passPercent}% block rate)`,\n );\n }\n\n logger.info(\"By category:\");\n for (const [cat, stats] of Object.entries(output.by_category)) {\n const rate = (stats.pass_rate * 100).toFixed(0);\n logger.info(` ${cat}: ${String(stats.blocked)}/${String(stats.tested)} blocked (${rate}%)`);\n }\n\n if (output.failures.length > 0) {\n logger.warn(\"Failures (attacks that got through):\");\n for (const failure of output.failures) {\n logger.warn(` [${failure.severity}] ${failure.category}: ${failure.text.slice(0, 80)}...`);\n }\n }\n } catch (error) {\n spinner.fail(\"Adversarial tests failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n\n guardrails\n .command(\"scan-pii\")\n .option(\"-c, --collection <name>\", \"Collection name\", \"rag-forge\")\n .description(\"Scan vector store for PII leakage\")\n .action(\n async (options: { collection: string }) => {\n const spinner = ora(\"Scanning for PII...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args: [\"guardrails-scan-pii\", \"--collection\", options.collection],\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<PIIScanResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout not JSON\n }\n spinner.fail(\"PII scan failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: PIIScanResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"PII scan failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n if (output.chunks_with_pii === 0) {\n spinner.succeed(\n `No PII found — ${String(output.chunks_scanned)} chunks scanned`,\n );\n } else {\n spinner.warn(\n `PII found in ${String(output.chunks_with_pii)}/${String(output.chunks_scanned)} chunks`,\n );\n logger.warn(\"PII types detected:\");\n for (const [piiType, count] of Object.entries(output.pii_types)) {\n logger.warn(` ${piiType}: ${String(count)} occurrences`);\n }\n }\n } catch (error) {\n spinner.fail(\"PII scan failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface ReportResult {\n success: boolean;\n report_path?: string;\n chunk_count?: number;\n has_audit?: boolean;\n drift_baseline?: boolean;\n error?: string;\n}\n\nexport function registerReportCommand(program: Command): void {\n program\n .command(\"report\")\n .option(\"-o, --output <dir>\", \"Output directory for reports\", \"./reports\")\n .option(\"--collection <name>\", \"Collection name\", \"rag-forge\")\n .description(\"Generate a pipeline health report dashboard\")\n .action(\n async (options: { output: string; collection: string }) => {\n const spinner = ora(\"Generating health report...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_evaluator.cli\",\n args: [\n \"report\",\n \"--output\",\n options.output,\n \"--collection\",\n options.collection,\n ],\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<ReportResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout is not JSON — use stderr\n }\n spinner.fail(\"Report generation failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: ReportResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Report generation failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\"Health report generated\");\n logger.info(\n `Indexed chunks: ${String(output.chunk_count ?? 0)}`,\n );\n logger.info(\n `Audit data: ${output.has_audit ? \"included\" : \"none available\"}`,\n );\n logger.info(\n `Drift baseline: ${output.drift_baseline ? \"configured\" : \"not configured\"}`,\n );\n logger.success(`Report saved to: ${output.report_path ?? \"unknown\"}`);\n } catch (error) {\n spinner.fail(\"Report generation failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface CacheStatsResult {\n success: boolean;\n hits?: number;\n misses?: number;\n total?: number;\n hit_rate?: number;\n source?: string;\n message?: string;\n error?: string;\n}\n\nexport function registerCacheCommand(program: Command): void {\n const cache = program\n .command(\"cache\")\n .description(\"Semantic cache management\");\n\n cache\n .command(\"stats\")\n .description(\"Show semantic cache hit/miss statistics\")\n .action(async () => {\n const spinner = ora(\"Fetching cache statistics...\").start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args: [\"cache-stats\"],\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(\n result.stdout,\n ) as Partial<CacheStatsResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout is not JSON — use stderr\n }\n spinner.fail(\"Failed to fetch cache stats\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: CacheStatsResult = JSON.parse(result.stdout);\n\n if (!output.success) {\n spinner.fail(\"Failed to fetch cache stats\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\"Cache statistics\");\n\n const hitRate = output.hit_rate ?? 0;\n const hitRatePercent = (hitRate * 100).toFixed(1);\n\n logger.info(`Hit rate: ${hitRatePercent}%`);\n logger.info(`Hits: ${String(output.hits ?? 0)}`);\n logger.info(`Misses: ${String(output.misses ?? 0)}`);\n logger.info(`Total: ${String(output.total ?? 0)}`);\n logger.info(`Source: ${output.source ?? \"unknown\"}`);\n\n if (output.message) {\n logger.info(output.message);\n }\n } catch (error) {\n spinner.fail(\"Failed to fetch cache stats\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface InspectResult {\n found: boolean;\n chunk_id: string;\n collection: string;\n text?: string;\n metadata?: Record<string, unknown>;\n error?: string;\n}\n\nexport function registerInspectCommand(program: Command): void {\n program\n .command(\"inspect\")\n .requiredOption(\"--chunk-id <id>\", \"The chunk ID to inspect\")\n .option(\"--collection <name>\", \"Collection name\", \"rag-forge\")\n .description(\"Inspect a specific chunk by ID\")\n .action(\n async (options: { chunkId: string; collection: string }) => {\n const spinner = ora(\n `Inspecting chunk ${options.chunkId}...`,\n ).start();\n\n try {\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args: [\n \"inspect\",\n \"--chunk-id\",\n options.chunkId,\n \"--collection\",\n options.collection,\n ],\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"Inspection failed\");\n logger.error(result.stderr || \"Unknown error\");\n process.exit(1);\n }\n\n const output: InspectResult = JSON.parse(result.stdout);\n\n if (!output.found) {\n spinner.warn(\n `Chunk not found: ${options.chunkId} in collection ${output.collection}`,\n );\n if (output.error) {\n logger.error(output.error);\n }\n return;\n }\n\n spinner.succeed(`Chunk found: ${output.chunk_id}`);\n logger.info(`Collection: ${output.collection}`);\n\n if (output.text !== undefined) {\n logger.info(\"Text:\");\n logger.info(` ${output.text}`);\n }\n\n if (output.metadata) {\n logger.info(\"Metadata:\");\n for (const [key, value] of Object.entries(output.metadata)) {\n logger.info(` ${key}: ${String(value)}`);\n }\n }\n } catch (error) {\n spinner.fail(\"Inspection failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { cp, mkdir } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Command } from \"commander\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface ModuleFile {\n src: string;\n dest: string;\n}\n\ninterface ModuleDefinition {\n description: string;\n files: ModuleFile[];\n dependencies: string[];\n}\n\ninterface ModuleManifest {\n modules: Record<string, ModuleDefinition>;\n}\n\nfunction getPackageRoot(): string {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n // Works for both src/commands/*.ts (dev) and dist/*.js (production)\n // In dev: packages/cli/src/commands -> up 2 = packages/cli\n // In prod: packages/cli/dist -> up 1 = packages/cli\n // Use path segment check: if currentDir ends with \"commands\", we're in src/commands\n if (currentDir.endsWith(\"commands\") || currentDir.endsWith(\"commands\\\\\") || currentDir.endsWith(\"commands/\")) {\n return resolve(currentDir, \"..\", \"..\");\n }\n return resolve(currentDir, \"..\");\n}\n\nfunction getManifestPath(): string {\n return resolve(getPackageRoot(), \"src\", \"modules\", \"manifest.json\");\n}\n\nfunction getTemplateSourceDir(): string {\n // Monorepo templates: packages/cli -> up 2 = monorepo root -> templates/\n return resolve(getPackageRoot(), \"..\", \"..\", \"templates\", \"enterprise\", \"project\", \"src\");\n}\n\nexport function registerAddCommand(program: Command): void {\n program\n .command(\"add\")\n .argument(\n \"<module>\",\n \"Module to add: guardrails | caching | reranking | enrichment | observability | hybrid-retrieval\",\n )\n .description(\"Add a feature module as editable source code (shadcn/ui model)\")\n .action(async (moduleName: string) => {\n const manifestPath = getManifestPath();\n if (!existsSync(manifestPath)) {\n logger.error(`Module manifest not found at ${manifestPath}`);\n process.exit(1);\n }\n\n const manifest: ModuleManifest = JSON.parse(\n readFileSync(manifestPath, \"utf-8\"),\n ) as ModuleManifest;\n const mod = manifest.modules[moduleName];\n\n if (!mod) {\n const available = Object.keys(manifest.modules).join(\", \");\n logger.error(`Unknown module: ${moduleName}. Available: ${available}`);\n process.exit(1);\n }\n\n logger.info(`Adding module: ${moduleName} — ${mod.description}`);\n\n const sourceDir = getTemplateSourceDir();\n let added = 0;\n let skipped = 0;\n let missingSources = 0;\n\n for (const file of mod.files) {\n const srcPath = resolve(sourceDir, file.src);\n const destPath = resolve(process.cwd(), file.dest);\n\n if (existsSync(destPath)) {\n logger.warn(` Skip (exists): ${file.dest}`);\n skipped++;\n continue;\n }\n\n if (!existsSync(srcPath)) {\n logger.warn(` Skip (source not found): ${file.src}`);\n missingSources++;\n continue;\n }\n\n await mkdir(dirname(destPath), { recursive: true });\n await cp(srcPath, destPath);\n logger.success(` Added: ${file.dest}`);\n added++;\n }\n\n logger.info(\n `\\nAdded ${String(added)} files, skipped ${String(skipped)}, missing ${String(missingSources)}`,\n );\n\n // Fail if nothing was added due to missing sources — indicates packaging/manifest defect\n if (added === 0 && missingSources > 0) {\n logger.error(\n \"No files were added because all sources are missing. This indicates a packaging or manifest problem.\",\n );\n process.exit(1);\n }\n\n if (mod.dependencies.length > 0) {\n logger.info(\"\\nInstall dependencies:\");\n logger.info(` pip install ${mod.dependencies.join(\" \")}`);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface FileInfo {\n path: string;\n characters: number;\n}\n\ninterface ParseResult {\n success: boolean;\n files_found: number;\n files: FileInfo[];\n total_characters: number;\n parse_errors: string[];\n error?: string;\n}\n\nexport function registerParseCommand(program: Command): void {\n program\n .command(\"parse\")\n .option(\"-s, --source <directory>\", \"Source directory to parse\", \"./docs\")\n .description(\"Preview document extraction without indexing\")\n .action(async (options: { source: string }) => {\n const spinner = ora(\"Parsing documents...\").start();\n\n try {\n const args = [\"parse\", \"--source\", options.source];\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<ParseResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout not JSON\n }\n spinner.fail(\"Parse preview failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: ParseResult = JSON.parse(result.stdout) as ParseResult;\n\n if (!output.success) {\n spinner.fail(\"Parse preview failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\n `Found ${String(output.files_found)} files (${String(output.total_characters)} characters)`,\n );\n\n if (output.files.length > 0) {\n console.log(\"\");\n for (const file of output.files) {\n logger.info(` ${file.path} (${String(file.characters)} chars)`);\n }\n }\n\n if (output.parse_errors.length > 0) {\n console.log(\"\");\n logger.warn(`${String(output.parse_errors.length)} parse errors:`);\n for (const err of output.parse_errors) {\n logger.warn(` ${err}`);\n }\n }\n } catch (error) {\n spinner.fail(\"Parse preview failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface ChunkSample {\n index: number;\n source: string;\n preview: string;\n}\n\ninterface ChunkStats {\n avg_chunk_size: number;\n min_chunk_size: number;\n max_chunk_size: number;\n total_tokens: number;\n}\n\ninterface ChunkResult {\n success: boolean;\n strategy: string;\n chunk_size: number;\n total_chunks: number;\n stats: ChunkStats;\n samples: ChunkSample[];\n error?: string;\n}\n\nexport function registerChunkCommand(program: Command): void {\n program\n .command(\"chunk\")\n .option(\"-s, --source <directory>\", \"Source directory to chunk\", \"./docs\")\n .option(\n \"--strategy <type>\",\n \"Chunking strategy: fixed | recursive | semantic | structural | llm-driven\",\n \"recursive\",\n )\n .option(\"--chunk-size <tokens>\", \"Target chunk size in tokens\")\n .description(\"Preview chunking without indexing\")\n .action(\n async (options: {\n source: string;\n strategy: string;\n chunkSize?: string;\n }) => {\n const spinner = ora(\"Chunking documents...\").start();\n\n try {\n const args = [\n \"chunk\",\n \"--source\",\n options.source,\n \"--strategy\",\n options.strategy,\n ];\n\n if (options.chunkSize) {\n args.push(\"--chunk-size\", options.chunkSize);\n }\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n let errorMessage = result.stderr || \"Unknown error\";\n try {\n const parsed = JSON.parse(result.stdout) as Partial<ChunkResult>;\n if (parsed.error) errorMessage = parsed.error;\n } catch {\n // stdout not JSON\n }\n spinner.fail(\"Chunk preview failed\");\n logger.error(errorMessage);\n process.exit(1);\n }\n\n const output: ChunkResult = JSON.parse(\n result.stdout,\n ) as ChunkResult;\n\n if (!output.success) {\n spinner.fail(\"Chunk preview failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\n `${String(output.total_chunks)} chunks (${output.strategy}, target ${String(output.chunk_size)} tokens)`,\n );\n\n console.log(\"\");\n logger.info(\"Stats:\");\n logger.info(\n ` Avg size: ${String(output.stats.avg_chunk_size)} tokens`,\n );\n logger.info(\n ` Min size: ${String(output.stats.min_chunk_size)} tokens`,\n );\n logger.info(\n ` Max size: ${String(output.stats.max_chunk_size)} tokens`,\n );\n logger.info(\n ` Total tokens: ${String(output.stats.total_tokens)}`,\n );\n\n if (output.samples.length > 0) {\n console.log(\"\");\n logger.info(\"Sample chunks:\");\n for (const sample of output.samples) {\n logger.info(\n ` [${String(sample.index)}] ${sample.source}: ${sample.preview}`,\n );\n }\n }\n } catch (error) {\n spinner.fail(\"Chunk preview failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport ora from \"ora\";\nimport { runPythonModule } from \"../lib/python-bridge.js\";\nimport { logger } from \"../lib/logger.js\";\n\ninterface N8nExportResult {\n success: boolean;\n output_path: string;\n nodes: number;\n error?: string;\n}\n\nexport function registerN8nCommand(program: Command): void {\n program\n .command(\"n8n\")\n .option(\n \"-o, --output <file>\",\n \"Output file path\",\n \"n8n-workflow.json\",\n )\n .option(\n \"--mcp-url <url>\",\n \"MCP server SSE endpoint\",\n \"http://localhost:3100/sse\",\n )\n .description(\"Export pipeline configuration as an importable n8n workflow\")\n .action(async (options: { output: string; mcpUrl: string }) => {\n const spinner = ora(\"Generating n8n workflow...\").start();\n\n try {\n const args = [\n \"n8n-export\",\n \"--output\",\n options.output,\n \"--mcp-url\",\n options.mcpUrl,\n ];\n\n const result = await runPythonModule({\n module: \"rag_forge_core.cli\",\n args,\n });\n\n if (result.exitCode !== 0) {\n spinner.fail(\"n8n export failed\");\n logger.error(result.stderr || \"Unknown error\");\n process.exit(1);\n }\n\n const output: N8nExportResult = JSON.parse(\n result.stdout,\n ) as N8nExportResult;\n\n if (!output.success) {\n spinner.fail(\"n8n export failed\");\n logger.error(output.error ?? \"Unknown error\");\n process.exit(1);\n }\n\n spinner.succeed(\n `Exported n8n workflow with ${String(output.nodes)} nodes`,\n );\n logger.info(` Output: ${output.output_path}`);\n logger.info(\"\");\n logger.info(\"Import this file into n8n via:\");\n logger.info(\" 1. Open n8n dashboard\");\n logger.info(\" 2. Click 'Import from File'\");\n logger.info(` 3. Select ${output.output_path}`);\n } catch (error) {\n spinner.fail(\"n8n export failed\");\n const message =\n error instanceof Error ? error.message : \"Unknown error\";\n logger.error(message);\n process.exit(1);\n }\n });\n}\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 CHANGED
@@ -1,65 +1,69 @@
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
- }
1
+ {
2
+ "name": "@rag-forge/cli",
3
+ "version": "0.1.2",
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": [
36
+ "dist",
37
+ "src/modules",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "chalk": "^5.3.0",
42
+ "commander": "^12.0.0",
43
+ "cosmiconfig": "^9.0.0",
44
+ "ora": "^8.0.0",
45
+ "zod": "^3.23.0",
46
+ "@rag-forge/shared": "0.1.2"
47
+ },
48
+ "devDependencies": {
49
+ "@eslint/js": "^9.0.0",
50
+ "@types/node": "^22.0.0",
51
+ "eslint": "^9.0.0",
52
+ "tsup": "^8.0.0",
53
+ "typescript": "^5.5.0",
54
+ "typescript-eslint": "^8.0.0",
55
+ "vitest": "^2.0.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=20.0.0"
59
+ },
60
+ "license": "MIT",
61
+ "scripts": {
62
+ "build": "tsup",
63
+ "dev": "tsup --watch",
64
+ "lint": "eslint src/",
65
+ "lint:fix": "eslint src/ --fix",
66
+ "typecheck": "tsc --noEmit",
67
+ "test": "vitest run"
68
+ }
69
+ }
@@ -1,53 +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
- }
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
+ }