@jcode.labs/ragmir 4.2.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -160
- package/dist/chunking.d.ts +1 -1
- package/dist/chunking.d.ts.map +1 -1
- package/dist/chunking.js +17 -1
- package/dist/chunking.js.map +1 -1
- package/dist/cli-entry.js +1 -1
- package/dist/cli-entry.js.map +1 -1
- package/dist/cli-fast.d.ts +1 -3
- package/dist/cli-fast.d.ts.map +1 -1
- package/dist/cli-fast.js +2 -104
- package/dist/cli-fast.js.map +1 -1
- package/dist/cli-options.d.ts +0 -37
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +0 -53
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +9 -701
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +1 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -36
- package/dist/client.js.map +1 -1
- package/dist/config-migration.d.ts +6 -0
- package/dist/config-migration.d.ts.map +1 -0
- package/dist/config-migration.js +31 -0
- package/dist/config-migration.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -65
- package/dist/config.js.map +1 -1
- package/dist/context-resources.d.ts.map +1 -1
- package/dist/context-resources.js +2 -14
- package/dist/context-resources.js.map +1 -1
- package/dist/defaults.d.ts +0 -3
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +0 -13
- package/dist/defaults.js.map +1 -1
- package/dist/destroy.d.ts.map +1 -1
- package/dist/destroy.js +0 -2
- package/dist/destroy.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +1 -9
- package/dist/doctor.js.map +1 -1
- package/dist/document-structure.js.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +9 -1
- package/dist/embeddings.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +0 -7
- package/dist/evaluate.js.map +1 -1
- package/dist/files.js.map +1 -1
- package/dist/generation-retention.js.map +1 -1
- package/dist/gitignore.js.map +1 -1
- package/dist/index-diagnostics.js +1 -1
- package/dist/index-diagnostics.js.map +1 -1
- package/dist/index-policy.d.ts.map +1 -1
- package/dist/index-policy.js +3 -4
- package/dist/index-policy.js.map +1 -1
- package/dist/index-write-lock.js.map +1 -1
- package/dist/index.d.ts +4 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/index.js.map +1 -1
- package/dist/ingest.d.ts.map +1 -1
- package/dist/ingest.js +3 -18
- package/dist/ingest.js.map +1 -1
- package/dist/ingestion-metrics.d.ts +1 -1
- package/dist/ingestion-metrics.d.ts.map +1 -1
- package/dist/ingestion-metrics.js +0 -1
- package/dist/ingestion-metrics.js.map +1 -1
- package/dist/ingestion-state.d.ts +1 -2
- package/dist/ingestion-state.d.ts.map +1 -1
- package/dist/ingestion-state.js +0 -2
- package/dist/ingestion-state.js.map +1 -1
- package/dist/lexical-scoring.d.ts +13 -0
- package/dist/lexical-scoring.d.ts.map +1 -0
- package/dist/lexical-scoring.js +35 -0
- package/dist/lexical-scoring.js.map +1 -0
- package/dist/mcp-output.d.ts +4 -31
- package/dist/mcp-output.d.ts.map +1 -1
- package/dist/mcp-output.js +4 -123
- package/dist/mcp-output.js.map +1 -1
- package/dist/mcp-summaries.d.ts +1 -12
- package/dist/mcp-summaries.d.ts.map +1 -1
- package/dist/mcp-summaries.js +0 -112
- package/dist/mcp-summaries.js.map +1 -1
- package/dist/mcp.d.ts +1 -5
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +22 -329
- package/dist/mcp.js.map +1 -1
- package/dist/ocr.d.ts +0 -1
- package/dist/ocr.d.ts.map +1 -1
- package/dist/ocr.js +0 -4
- package/dist/ocr.js.map +1 -1
- package/dist/parsing.js +13 -0
- package/dist/parsing.js.map +1 -1
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +2 -5
- package/dist/preview.js.map +1 -1
- package/dist/query-sanitizer.d.ts +2 -1
- package/dist/query-sanitizer.d.ts.map +1 -1
- package/dist/query-sanitizer.js +9 -127
- package/dist/query-sanitizer.js.map +1 -1
- package/dist/query.d.ts +1 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +95 -71
- package/dist/query.js.map +1 -1
- package/dist/ranking.d.ts +1 -1
- package/dist/ranking.d.ts.map +1 -1
- package/dist/ranking.js +52 -41
- package/dist/ranking.js.map +1 -1
- package/dist/runtime-info.js.map +1 -1
- package/dist/search-output.d.ts +3 -0
- package/dist/search-output.d.ts.map +1 -0
- package/dist/search-output.js +26 -0
- package/dist/search-output.js.map +1 -0
- package/dist/security.d.ts.map +1 -1
- package/dist/security.js +5 -37
- package/dist/security.js.map +1 -1
- package/dist/setup-prompt.d.ts +1 -1
- package/dist/setup-prompt.d.ts.map +1 -1
- package/dist/setup-prompt.js +22 -25
- package/dist/setup-prompt.js.map +1 -1
- package/dist/setup.js +1 -1
- package/dist/setup.js.map +1 -1
- package/dist/skill.d.ts +1 -4
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +3 -71
- package/dist/skill.js.map +1 -1
- package/dist/storage-maintenance.js.map +1 -1
- package/dist/store.js +9 -1
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +19 -156
- package/dist/types.d.ts.map +1 -1
- package/dist/upgrade.d.ts +3 -2
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +20 -2
- package/dist/upgrade.js.map +1 -1
- package/dist/vector-index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workload.js.map +1 -1
- package/examples/document-evidence-benchmark/.ragmir/config.json +0 -9
- package/examples/document-evidence-benchmark/README.md +5 -3
- package/examples/document-evidence-benchmark/raw/rfp/security-questionnaire.md +1 -1
- package/examples/library-api-demo/README.md +17 -8
- package/examples/library-api-demo/run.mjs +6 -6
- package/examples/sovereign-rag-demo/.ragmir/config.json +3 -10
- package/examples/sovereign-rag-demo/README.md +21 -12
- package/package.json +21 -30
- package/skills/ragmir/SKILL.md +67 -199
- package/dist/access-log.d.ts +0 -30
- package/dist/access-log.d.ts.map +0 -1
- package/dist/access-log.js +0 -415
- package/dist/access-log.js.map +0 -1
- package/dist/cli-stdin.d.ts +0 -3
- package/dist/cli-stdin.d.ts.map +0 -1
- package/dist/cli-stdin.js +0 -15
- package/dist/cli-stdin.js.map +0 -1
- package/dist/portable-entry.d.ts +0 -5
- package/dist/portable-entry.d.ts.map +0 -1
- package/dist/portable-entry.js +0 -337
- package/dist/portable-entry.js.map +0 -1
- package/dist/portable.d.ts +0 -89
- package/dist/portable.d.ts.map +0 -1
- package/dist/portable.js +0 -1290
- package/dist/portable.js.map +0 -1
- package/dist/prompt-routing.d.ts +0 -12
- package/dist/prompt-routing.d.ts.map +0 -1
- package/dist/prompt-routing.js +0 -150
- package/dist/prompt-routing.js.map +0 -1
- package/dist/redaction.d.ts +0 -12
- package/dist/redaction.d.ts.map +0 -1
- package/dist/redaction.js +0 -253
- package/dist/redaction.js.map +0 -1
- package/dist/research.d.ts +0 -21
- package/dist/research.d.ts.map +0 -1
- package/dist/research.js +0 -667
- package/dist/research.js.map +0 -1
- package/dist/team-diagnostics.d.ts +0 -119
- package/dist/team-diagnostics.d.ts.map +0 -1
- package/dist/team-diagnostics.js +0 -515
- package/dist/team-diagnostics.js.map +0 -1
- package/dist/team-sync.d.ts +0 -49
- package/dist/team-sync.d.ts.map +0 -1
- package/dist/team-sync.js +0 -436
- package/dist/team-sync.js.map +0 -1
- package/skills/ragmir-audio-summary/SKILL.md +0 -80
- package/skills/ragmir-audio-summary/forge-voice.sh +0 -150
- package/skills/ragmir-audio-summary/listening-style.md +0 -92
- package/skills/ragmir-audio-summary/narration-templates.md +0 -162
- package/skills/ragmir-audio-summary/split-lines.py +0 -14
- package/skills/ragmir-audio-summary/xtts-voice.py +0 -46
- package/skills/ragmir-legal-dossier/SKILL.md +0 -143
- package/skills/ragmir-markdown-report/SKILL.md +0 -110
package/dist/cli.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import pc from "picocolors";
|
|
5
|
-
import {
|
|
6
|
-
import { audioAllowRemoteModels, audioEngine, audioLanguage, parseAgentInstallMode, parseAgentInstallScope, parseIncrementalFailurePolicy, parseNonNegativeInt, parseNumber, parsePositiveInt, parseRecallThreshold, } from "./cli-options.js";
|
|
7
|
-
import { readBoundedStdin } from "./cli-stdin.js";
|
|
5
|
+
import { parseAgentInstallMode, parseAgentInstallScope, parseIncrementalFailurePolicy, parseNonNegativeInt, parsePositiveInt, parseRecallThreshold, } from "./cli-options.js";
|
|
8
6
|
import { loadConfig } from "./config.js";
|
|
9
7
|
import { DEFAULT_SKILL_TARGET_DIR } from "./defaults.js";
|
|
10
8
|
import { destroyIndex } from "./destroy.js";
|
|
@@ -22,11 +20,9 @@ import { ingestionLimits } from "./limits.js";
|
|
|
22
20
|
import { serveMcp } from "./mcp.js";
|
|
23
21
|
import { configurePdfOcr, extractPdfPage, extractPdfPages, inspectPdfOcr, parsePdfOcrEngine, parsePdfOcrPages, } from "./ocr.js";
|
|
24
22
|
import { rgrCommand } from "./package-manager.js";
|
|
25
|
-
import { exportPortableKnowledgeBase, verifyPortableKnowledgeBase } from "./portable.js";
|
|
26
23
|
import { previewChunks } from "./preview.js";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { compactResearchReport, compactSearchResults, research } from "./research.js";
|
|
24
|
+
import { search } from "./query.js";
|
|
25
|
+
import { compactSearchResults } from "./search-output.js";
|
|
30
26
|
import { securityAudit } from "./security.js";
|
|
31
27
|
import { enableSemanticEmbeddings } from "./semantic-config.js";
|
|
32
28
|
import { setupProject } from "./setup.js";
|
|
@@ -34,21 +30,11 @@ import { bundledSkillPath, installAgentSkills, installSkill, parseAgentTargets,
|
|
|
34
30
|
import { addSourceEntries, listSourceEntries } from "./sources.js";
|
|
35
31
|
import { optimizeStorage } from "./storage-maintenance.js";
|
|
36
32
|
import { readIndexManifestHeader } from "./store.js";
|
|
37
|
-
import { compareTeamSnapshots, createTeamSnapshot, readTeamSnapshot, writeTeamSnapshot, } from "./team-diagnostics.js";
|
|
38
|
-
import { syncTeamKnowledge, } from "./team-sync.js";
|
|
39
33
|
import { inspectUpgrade, upgradeProject } from "./upgrade.js";
|
|
40
34
|
import { VERSION } from "./version.js";
|
|
41
35
|
const SEARCH_TEXT_PREVIEW_LENGTH = 900;
|
|
42
|
-
const CHAT_PACKAGE_NAME = "@jcode.labs/ragmir-chat";
|
|
43
|
-
const TTS_PACKAGE_NAME = "@jcode.labs/ragmir-tts";
|
|
44
|
-
const DEPRECATED_CLI_NAMES = new Set(["ragmir", "kb"]);
|
|
45
36
|
const PUBLIC_CLI_NAME = "rgr";
|
|
46
|
-
const TEAM_DIFF_PREVIEW_LIMIT = 20;
|
|
47
37
|
const program = new Command();
|
|
48
|
-
const deprecatedCliName = deprecatedCliInvocation();
|
|
49
|
-
if (deprecatedCliName !== null) {
|
|
50
|
-
console.error(pc.yellow(`The \`${deprecatedCliName}\` CLI command is deprecated and will be removed in a future release. Use \`rgr\` instead.`));
|
|
51
|
-
}
|
|
52
38
|
program
|
|
53
39
|
.name(PUBLIC_CLI_NAME)
|
|
54
40
|
.description("Local-first RAG knowledge base for private project documents.")
|
|
@@ -175,7 +161,7 @@ ocrCommand
|
|
|
175
161
|
});
|
|
176
162
|
program
|
|
177
163
|
.command("doctor")
|
|
178
|
-
.description("Diagnose setup, index freshness,
|
|
164
|
+
.description("Diagnose setup, index freshness, and next steps.")
|
|
179
165
|
.option("--fix", "Create missing scaffolding, install the agent kit, and rebuild stale indexes.")
|
|
180
166
|
.option("--deep", "Run the O(corpus) source inventory and executable security probes.")
|
|
181
167
|
.option("--json", "Print machine-readable JSON.")
|
|
@@ -215,7 +201,6 @@ program
|
|
|
215
201
|
console.log(`runtimeRagmirVersion=${inspection.runtimeRagmirVersion}`);
|
|
216
202
|
console.log(`indexedWithRagmirVersion=${inspection.indexedWithRagmirVersion ?? "unavailable"}`);
|
|
217
203
|
console.log(`ready=${inspection.ready}`);
|
|
218
|
-
console.log(`privacyCompliant=${inspection.privacyCompliant}`);
|
|
219
204
|
console.log(`safeActivation=${inspection.safeActivation}`);
|
|
220
205
|
if (inspection.reason) {
|
|
221
206
|
console.log(`reason=${inspection.reason}`);
|
|
@@ -237,7 +222,6 @@ program
|
|
|
237
222
|
console.log(`runtimeRagmirVersion=${result.runtimeRagmirVersion}`);
|
|
238
223
|
console.log(`indexedWithRagmirVersion=${result.indexedWithRagmirVersion ?? "unavailable"}`);
|
|
239
224
|
console.log(`ready=${result.ready}`);
|
|
240
|
-
console.log(`privacyCompliant=${result.privacyCompliant}`);
|
|
241
225
|
console.log(`safeActivation=${result.safeActivation}`);
|
|
242
226
|
console.log(`action=${result.action}`);
|
|
243
227
|
console.log(`previousIndexedWithRagmirVersion=${result.previousIndexedWithRagmirVersion ?? "unavailable"}`);
|
|
@@ -358,7 +342,7 @@ sourcesCommand
|
|
|
358
342
|
});
|
|
359
343
|
program
|
|
360
344
|
.command("ingest")
|
|
361
|
-
.description("Parse changed documents,
|
|
345
|
+
.description("Parse changed documents, chunk, embed locally, and update LanceDB.")
|
|
362
346
|
.option("--rebuild", "Force a full local index rebuild instead of reusing unchanged rows.")
|
|
363
347
|
.option("--batch-size <number>", "Files committed per resumable batch.", parsePositiveInt)
|
|
364
348
|
.option("--incremental-failure-policy <policy>", "Preserve last-good rows after a file failure, or remove stale rows.", parseIncrementalFailurePolicy)
|
|
@@ -379,7 +363,7 @@ program
|
|
|
379
363
|
}
|
|
380
364
|
return;
|
|
381
365
|
}
|
|
382
|
-
console.log(pc.green(`Done. runId=${result.runId} resumed=${result.resumed} batchSize=${result.batchSize} discoveredFiles=${result.discoveredFiles} supportedFiles=${result.supportedFiles} supportedBytes=${result.supportedBytes} largestFileBytes=${result.largestFileBytes} indexedFiles=${result.indexedFiles} rebuiltFiles=${result.rebuiltFiles} reusedFiles=${result.reusedFiles} staleLastKnownGood=${result.staleLastKnownGood.length} chunks=${result.chunks} skippedFiles=${result.skippedFiles} unsupportedFiles=${result.unsupportedFiles} oversizedFiles=${result.oversizedFiles} sensitiveFiles=${result.sensitiveFiles} emptyTextFiles=${result.emptyTextFiles.length}
|
|
366
|
+
console.log(pc.green(`Done. runId=${result.runId} resumed=${result.resumed} batchSize=${result.batchSize} discoveredFiles=${result.discoveredFiles} supportedFiles=${result.supportedFiles} supportedBytes=${result.supportedBytes} largestFileBytes=${result.largestFileBytes} indexedFiles=${result.indexedFiles} rebuiltFiles=${result.rebuiltFiles} reusedFiles=${result.reusedFiles} staleLastKnownGood=${result.staleLastKnownGood.length} chunks=${result.chunks} skippedFiles=${result.skippedFiles} unsupportedFiles=${result.unsupportedFiles} oversizedFiles=${result.oversizedFiles} sensitiveFiles=${result.sensitiveFiles} emptyTextFiles=${result.emptyTextFiles.length} ocrPages=${result.ocr.pages} ocrCacheHits=${result.ocr.cacheHits} ocrBatches=${result.ocr.batches} ocrSubprocesses=${result.ocr.subprocesses} ocrDurationMs=${result.ocr.durationMs} errors=${result.errors.length}`));
|
|
383
367
|
printUnsupportedSummary(result.unsupportedExtensions);
|
|
384
368
|
printEmptyTextFiles(result.emptyTextFiles);
|
|
385
369
|
if (result.vectorIndexWarning) {
|
|
@@ -404,7 +388,7 @@ program
|
|
|
404
388
|
});
|
|
405
389
|
program
|
|
406
390
|
.command("preview")
|
|
407
|
-
.description("Preview
|
|
391
|
+
.description("Preview source chunks and structure without writing the index.")
|
|
408
392
|
.option("--path <prefix>", "Preview only source paths under this prefix. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
409
393
|
.option("--max-files <number>", "Maximum number of matching files to parse.", parsePositiveInt)
|
|
410
394
|
.option("--max-chunks <number>", "Maximum number of chunks to show per file.", parsePositiveInt)
|
|
@@ -434,7 +418,7 @@ program
|
|
|
434
418
|
console.log(pc.yellow(`unmatched: ${unmatchedPath}`));
|
|
435
419
|
}
|
|
436
420
|
for (const file of report.files) {
|
|
437
|
-
console.log(`\n${pc.cyan(file.relativePath)} chunks=${file.chunkStats.count}
|
|
421
|
+
console.log(`\n${pc.cyan(file.relativePath)} chunks=${file.chunkStats.count} minChars=${file.chunkStats.minChars} p50Chars=${file.chunkStats.p50Chars} p95Chars=${file.chunkStats.p95Chars} maxChars=${file.chunkStats.maxChars} contextualRatio=${file.chunkStats.contextualRatio.toFixed(3)}`);
|
|
438
422
|
if (file.ocr) {
|
|
439
423
|
console.log(`ocrPages=${file.ocr.pages} ocrCacheHits=${file.ocr.cacheHits} ocrBatches=${file.ocr.batches} ocrSubprocesses=${file.ocr.subprocesses} ocrDurationMs=${file.ocr.durationMs}`);
|
|
440
424
|
}
|
|
@@ -497,112 +481,6 @@ program
|
|
|
497
481
|
}
|
|
498
482
|
}
|
|
499
483
|
});
|
|
500
|
-
program
|
|
501
|
-
.command("ask")
|
|
502
|
-
.description("Return cited retrieval context for a question without calling an LLM.")
|
|
503
|
-
.argument("<query>", "Question to answer.")
|
|
504
|
-
.option("-k, --top-k <number>", "Number of passages to use.", parsePositiveInt)
|
|
505
|
-
.option("--max-chunks-per-document <number>", "Maximum primary passages per document before ranked backfill.", parsePositiveInt)
|
|
506
|
-
.option("--context-radius <number>", "Include neighboring chunks around each matched passage.", parseNonNegativeInt)
|
|
507
|
-
.option("--include-path <prefix>", "Use only indexed source paths under this prefix. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
508
|
-
.option("--exclude-path <prefix>", "Exclude indexed source paths under this prefix. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
509
|
-
.option("--context-path <prefix>", "Use only chunks under this structural context. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
510
|
-
.option("--explain", "Include hybrid score contributions, ranks, and matched terms.")
|
|
511
|
-
.option("--exact-vector-search", "Bypass ANN and use exhaustive vector search for diagnostics.")
|
|
512
|
-
.option("--json", "Print machine-readable JSON.")
|
|
513
|
-
.action(async (query, options, command) => {
|
|
514
|
-
const cwd = projectRoot(command);
|
|
515
|
-
const result = await ask(query, withSearchOptions(cwd, options));
|
|
516
|
-
if (options.json) {
|
|
517
|
-
console.log(JSON.stringify({ query, ...result }, null, 2));
|
|
518
|
-
if (result.sources.length === 0) {
|
|
519
|
-
process.exitCode = 1;
|
|
520
|
-
}
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
console.log(`\n${result.answer}\n`);
|
|
524
|
-
if (result.staleWarning) {
|
|
525
|
-
console.error(pc.yellow(result.staleWarning));
|
|
526
|
-
}
|
|
527
|
-
if (result.sources.length > 0) {
|
|
528
|
-
console.log(pc.dim("Sources:"));
|
|
529
|
-
for (const [index, source] of result.sources.entries()) {
|
|
530
|
-
const score = source.score ? ` score=${source.score.combinedScore.toFixed(6)}` : "";
|
|
531
|
-
console.log(` [${index + 1}] ${source.citation} chunk=${source.chunkIndex}${score}`);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
program
|
|
536
|
-
.command("research")
|
|
537
|
-
.description("Run a bounded multi-query research pass with cited evidence.")
|
|
538
|
-
.argument("<query>", "Research question or topic.")
|
|
539
|
-
.option("-k, --top-k <number>", "Maximum number of evidence passages to keep.", parsePositiveInt)
|
|
540
|
-
.option("--no-code", "Skip the lightweight repository code search.")
|
|
541
|
-
.option("--full-audit", "Run a full source inventory instead of manifest health checks.")
|
|
542
|
-
.option("--timeout-ms <number>", "Bound the complete research operation.", parsePositiveInt)
|
|
543
|
-
.option("--code-top-k <number>", "Maximum number of code matches to keep.", parsePositiveInt)
|
|
544
|
-
.option("--code-scan-max-files <number>", "Maximum code files to read.", parsePositiveInt)
|
|
545
|
-
.option("--code-scan-max-bytes <number>", "Maximum total code bytes to read.", parsePositiveInt)
|
|
546
|
-
.option("--code-scan-concurrency <number>", "Maximum concurrent code file reads.", parsePositiveInt)
|
|
547
|
-
.option("--include-path <prefix>", "Use only indexed source paths under this prefix. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
548
|
-
.option("--exclude-path <prefix>", "Exclude indexed source paths under this prefix. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
549
|
-
.option("--context-path <prefix>", "Use only chunks under this structural context. Repeat for multiple prefixes.", collectOptionValue, [])
|
|
550
|
-
.option("--compact", "Return snippets instead of full retrieved passages.")
|
|
551
|
-
.option("--json", "Print machine-readable JSON.")
|
|
552
|
-
.action(async (query, options, command) => {
|
|
553
|
-
const cwd = projectRoot(command);
|
|
554
|
-
const researchOptions = { cwd };
|
|
555
|
-
addOption(researchOptions, "topK", options.topK);
|
|
556
|
-
addOption(researchOptions, "includeCode", options.code);
|
|
557
|
-
addOption(researchOptions, "fullAudit", options.fullAudit);
|
|
558
|
-
addOption(researchOptions, "timeoutMs", options.timeoutMs);
|
|
559
|
-
addOption(researchOptions, "codeTopK", options.codeTopK);
|
|
560
|
-
addOption(researchOptions, "codeScanMaxFiles", options.codeScanMaxFiles);
|
|
561
|
-
addOption(researchOptions, "codeScanMaxBytes", options.codeScanMaxBytes);
|
|
562
|
-
addOption(researchOptions, "codeScanConcurrency", options.codeScanConcurrency);
|
|
563
|
-
addPathFilters(researchOptions, options);
|
|
564
|
-
const report = await research(query, researchOptions);
|
|
565
|
-
const output = options.compact ? compactResearchReport(report) : report;
|
|
566
|
-
if (options.json) {
|
|
567
|
-
console.log(JSON.stringify(output, null, 2));
|
|
568
|
-
if (!report.ready) {
|
|
569
|
-
process.exitCode = 1;
|
|
570
|
-
}
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
printResearchReport(output);
|
|
574
|
-
if (!report.ready) {
|
|
575
|
-
process.exitCode = 1;
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
program
|
|
579
|
-
.command("route-prompt")
|
|
580
|
-
.description("Classify a prompt and suggest whether an agent should use Ragmir local context.")
|
|
581
|
-
.argument("[prompt...]", "Prompt text to classify. Reads stdin when omitted.")
|
|
582
|
-
.option("--json", "Print machine-readable JSON.")
|
|
583
|
-
.action(async (promptParts, options) => {
|
|
584
|
-
const prompt = await promptInput(promptParts);
|
|
585
|
-
if (prompt.trim().length === 0) {
|
|
586
|
-
console.error(pc.red("Missing prompt. Pass text or pipe it on stdin."));
|
|
587
|
-
process.exitCode = 1;
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
const decision = routePrompt(prompt);
|
|
591
|
-
if (options.json) {
|
|
592
|
-
console.log(JSON.stringify(decision, null, 2));
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
console.log(`shouldUseRagmir=${decision.shouldUseRagmir}`);
|
|
596
|
-
console.log(`confidence=${decision.confidence.toFixed(2)}`);
|
|
597
|
-
console.log(`tool=${decision.tool}`);
|
|
598
|
-
if (decision.query !== null) {
|
|
599
|
-
console.log(`query=${decision.query}`);
|
|
600
|
-
}
|
|
601
|
-
console.log(`reason=${decision.reason}`);
|
|
602
|
-
if (decision.matchedSignals.length > 0) {
|
|
603
|
-
console.log(`matchedSignals=${decision.matchedSignals.join(", ")}`);
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
484
|
program
|
|
607
485
|
.command("evaluate")
|
|
608
486
|
.description("Measure retrieval quality against a JSON golden query file.")
|
|
@@ -724,33 +602,6 @@ program
|
|
|
724
602
|
process.exitCode = 1;
|
|
725
603
|
}
|
|
726
604
|
});
|
|
727
|
-
program
|
|
728
|
-
.command("usage-report")
|
|
729
|
-
.description("Summarize the metadata-only local access log.")
|
|
730
|
-
.option("--days <number>", "Number of recent days to include.", parsePositiveInt, 7)
|
|
731
|
-
.option("--json", "Print machine-readable JSON.")
|
|
732
|
-
.action(async (options, command) => {
|
|
733
|
-
const cwd = projectRoot(command);
|
|
734
|
-
const report = await accessLogUsageReport({ cwd, days: options.days });
|
|
735
|
-
if (options.json) {
|
|
736
|
-
console.log(JSON.stringify(report, null, 2));
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
console.log(`accessLogEnabled=${report.accessLogEnabled}`);
|
|
740
|
-
console.log(`since=${report.since}`);
|
|
741
|
-
console.log(`until=${report.until}`);
|
|
742
|
-
console.log(`totalEvents=${report.totalEvents}`);
|
|
743
|
-
console.log(`invalidLines=${report.invalidLines}`);
|
|
744
|
-
console.log(`uniqueQueryHashes=${report.uniqueQueryHashes}`);
|
|
745
|
-
console.log(`averageResultCount=${report.averageResultCount ?? "n/a"}`);
|
|
746
|
-
console.log(`lastEventAt=${report.lastEventAt ?? "n/a"}`);
|
|
747
|
-
for (const [action, count] of Object.entries(report.eventsByAction)) {
|
|
748
|
-
console.log(`events.${action}=${count}`);
|
|
749
|
-
}
|
|
750
|
-
for (const [action, average] of Object.entries(report.averageResultCountByAction)) {
|
|
751
|
-
console.log(`averageResults.${action}=${average ?? "n/a"}`);
|
|
752
|
-
}
|
|
753
|
-
});
|
|
754
605
|
program
|
|
755
606
|
.command("limits")
|
|
756
607
|
.description("Show active ingestion limits and practical corpus scaling boundaries.")
|
|
@@ -802,84 +653,6 @@ program
|
|
|
802
653
|
console.log(`${marker} ${base.id} format=${format} root=${base.projectRoot}`);
|
|
803
654
|
}
|
|
804
655
|
});
|
|
805
|
-
const teamCommand = program
|
|
806
|
-
.command("team")
|
|
807
|
-
.description("Synchronize Git-backed team knowledge or inspect advanced index drift.");
|
|
808
|
-
teamCommand
|
|
809
|
-
.command("sync")
|
|
810
|
-
.description("Safely fast-forward from Git upstream and refresh the local index.")
|
|
811
|
-
.option("--no-pull", "Fetch and compare without changing the checked-out branch.")
|
|
812
|
-
.option("--no-fetch", "Use only the cached upstream reference and local worktree.")
|
|
813
|
-
.option("--check", "Fetch and report without changing the worktree or index.")
|
|
814
|
-
.option("--git-timeout-ms <number>", "Bound each Git command.", parsePositiveInt)
|
|
815
|
-
.option("--json", "Print machine-readable JSON.")
|
|
816
|
-
.option("--strict", "Exit with code 1 unless Git and the local index are synchronized.")
|
|
817
|
-
.action(async (options, command) => {
|
|
818
|
-
const syncOptions = {
|
|
819
|
-
cwd: projectRoot(command),
|
|
820
|
-
autoPull: options.pull,
|
|
821
|
-
fetch: options.fetch,
|
|
822
|
-
check: options.check === true,
|
|
823
|
-
};
|
|
824
|
-
addOption(syncOptions, "gitTimeoutMs", options.gitTimeoutMs);
|
|
825
|
-
const report = await syncTeamKnowledge(syncOptions);
|
|
826
|
-
if (options.json) {
|
|
827
|
-
console.log(JSON.stringify(report, null, 2));
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
printTeamSync(report);
|
|
831
|
-
}
|
|
832
|
-
if (options.strict && !report.synchronized) {
|
|
833
|
-
process.exitCode = 1;
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
teamCommand
|
|
837
|
-
.command("snapshot")
|
|
838
|
-
.description("Export relative paths, checksums, configuration, readiness, and corpus identity.")
|
|
839
|
-
.requiredOption("--output <path>", "Snapshot file to create or replace.")
|
|
840
|
-
.option("--label <label>", "Human-readable environment label.", "local")
|
|
841
|
-
.option("--json", "Print machine-readable JSON.")
|
|
842
|
-
.action(async (options, command) => {
|
|
843
|
-
const cwd = projectRoot(command);
|
|
844
|
-
const snapshot = await createTeamSnapshot({ cwd, label: options.label });
|
|
845
|
-
const outputPath = await writeTeamSnapshot(snapshot, path.resolve(cwd, options.output));
|
|
846
|
-
if (options.json) {
|
|
847
|
-
console.log(JSON.stringify({ outputPath, snapshot }, null, 2));
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
console.log(pc.green("Team snapshot ready."));
|
|
851
|
-
console.log(`outputPath=${outputPath}`);
|
|
852
|
-
console.log(`label=${snapshot.label}`);
|
|
853
|
-
console.log(`ready=${snapshot.ready}`);
|
|
854
|
-
console.log(`securityAdvisories=${snapshot.health.securityWarnings}`);
|
|
855
|
-
console.log(`corpusFingerprint=${snapshot.corpus.fingerprint ?? "unavailable"}`);
|
|
856
|
-
console.log(`indexedFiles=${snapshot.corpus.indexedFiles}`);
|
|
857
|
-
console.log(`notice=${snapshot.notice}`);
|
|
858
|
-
});
|
|
859
|
-
teamCommand
|
|
860
|
-
.command("compare")
|
|
861
|
-
.description("Compare the current local index with a peer snapshot and print actionable drift.")
|
|
862
|
-
.argument("<snapshot>", "Peer snapshot created by `rgr team snapshot`.")
|
|
863
|
-
.option("--local-label <label>", "Human-readable label for this environment.", "local")
|
|
864
|
-
.option("--json", "Print machine-readable JSON.")
|
|
865
|
-
.option("--strict", "Exit with code 1 unless both indexes are synchronized.")
|
|
866
|
-
.action(async (snapshotPath, options, command) => {
|
|
867
|
-
const cwd = projectRoot(command);
|
|
868
|
-
const [local, peer] = await Promise.all([
|
|
869
|
-
createTeamSnapshot({ cwd, label: options.localLabel }),
|
|
870
|
-
readTeamSnapshot(path.resolve(cwd, snapshotPath)),
|
|
871
|
-
]);
|
|
872
|
-
const comparison = compareTeamSnapshots(local, peer);
|
|
873
|
-
if (options.json) {
|
|
874
|
-
console.log(JSON.stringify(comparison, null, 2));
|
|
875
|
-
}
|
|
876
|
-
else {
|
|
877
|
-
printTeamComparison(comparison);
|
|
878
|
-
}
|
|
879
|
-
if (options.strict && !comparison.synchronized) {
|
|
880
|
-
process.exitCode = 1;
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
656
|
program
|
|
884
657
|
.command("status")
|
|
885
658
|
.description("Show active configuration, readiness, corpus fingerprint, and index counts.")
|
|
@@ -907,13 +680,10 @@ program
|
|
|
907
680
|
rawDir: config.rawDir,
|
|
908
681
|
storageDir: config.storageDir,
|
|
909
682
|
sourcesFile: config.sourcesFile,
|
|
910
|
-
accessLogPath: config.accessLogPath,
|
|
911
683
|
embeddingModelPath: config.embeddingModelPath,
|
|
912
684
|
embeddingProvider: config.embeddingProvider,
|
|
913
685
|
embeddingModel: config.embeddingModel,
|
|
914
686
|
transformersAllowRemoteModels: config.transformersAllowRemoteModels,
|
|
915
|
-
redactionEnabled: config.redaction.enabled,
|
|
916
|
-
accessLog: config.accessLog,
|
|
917
687
|
mcpMaxTopK: config.mcpMaxTopK,
|
|
918
688
|
mcpMaxOutputBytes: config.mcpMaxOutputBytes,
|
|
919
689
|
topK: config.topK,
|
|
@@ -949,13 +719,10 @@ program
|
|
|
949
719
|
console.log(`rawDir=${config.rawDir}`);
|
|
950
720
|
console.log(`storageDir=${config.storageDir}`);
|
|
951
721
|
console.log(`sourcesFile=${config.sourcesFile}`);
|
|
952
|
-
console.log(`accessLogPath=${config.accessLogPath}`);
|
|
953
722
|
console.log(`embeddingModelPath=${config.embeddingModelPath}`);
|
|
954
723
|
console.log(`embeddingProvider=${config.embeddingProvider}`);
|
|
955
724
|
console.log(`embeddingModel=${config.embeddingModel}`);
|
|
956
725
|
console.log(`transformersAllowRemoteModels=${config.transformersAllowRemoteModels}`);
|
|
957
|
-
console.log(`redactionEnabled=${config.redaction.enabled}`);
|
|
958
|
-
console.log(`accessLog=${config.accessLog}`);
|
|
959
726
|
console.log(`mcpMaxTopK=${config.mcpMaxTopK}`);
|
|
960
727
|
console.log(`mcpMaxOutputBytes=${config.mcpMaxOutputBytes}`);
|
|
961
728
|
console.log(`topK=${config.topK}`);
|
|
@@ -992,7 +759,7 @@ program
|
|
|
992
759
|
});
|
|
993
760
|
program
|
|
994
761
|
.command("security-audit")
|
|
995
|
-
.description("Show local
|
|
762
|
+
.description("Show local providers, file permissions, MCP bounds, and Git exclusions.")
|
|
996
763
|
.option("--json", "Print machine-readable JSON.")
|
|
997
764
|
.option("--strict", "Exit with code 1 when warnings are present.")
|
|
998
765
|
.action(async (options, command) => {
|
|
@@ -1008,10 +775,6 @@ program
|
|
|
1008
775
|
console.log(`embeddingModelPath=${report.providers.embeddingModelPath}`);
|
|
1009
776
|
console.log(`transformersAllowRemoteModels=${report.providers.transformersAllowRemoteModels}`);
|
|
1010
777
|
console.log(`llmGeneration=${report.providers.llmGeneration}`);
|
|
1011
|
-
console.log(`redactionEnabled=${report.redaction.enabled}`);
|
|
1012
|
-
console.log(`redactionBuiltIn=${report.redaction.builtIn}`);
|
|
1013
|
-
console.log(`accessLog=${report.accessLog.enabled}`);
|
|
1014
|
-
console.log(`accessLogStoresRawQueries=${report.accessLog.storesRawQueries}`);
|
|
1015
778
|
console.log(`storageGitIgnored=${report.storage.gitIgnored}`);
|
|
1016
779
|
console.log(`mcpMaxTopK=${report.mcp.maxTopK}`);
|
|
1017
780
|
console.log(`mcpMaxOutputBytes=${report.mcp.maxOutputBytes}`);
|
|
@@ -1100,131 +863,6 @@ program
|
|
|
1100
863
|
console.log(`removed=${result.removed}`);
|
|
1101
864
|
console.log(result.note);
|
|
1102
865
|
});
|
|
1103
|
-
program
|
|
1104
|
-
.command("chat")
|
|
1105
|
-
.description("Answer with a verified local model grounded in Ragmir citations.")
|
|
1106
|
-
.argument("[input...]", "Question to answer, or `setup` / `doctor`.")
|
|
1107
|
-
.option("-k, --top-k <number>", "Number of passages to retrieve.", parsePositiveInt)
|
|
1108
|
-
.option("--profile <profile>", "Local chat profile: lite, fast, or quality.")
|
|
1109
|
-
.option("--thinking <mode>", "Thinking mode: off, standard, or deep.")
|
|
1110
|
-
.option("--model-path <path>", "Local Gemma model root.")
|
|
1111
|
-
.option("--offline", "Require an already verified local model.")
|
|
1112
|
-
.option("--allow-remote-models", "Compatibility flag for explicit chat setup; normal answers stay local.")
|
|
1113
|
-
.option("--verify", "Recompute the full model SHA256 during doctor.")
|
|
1114
|
-
.option("--max-new-tokens <number>", "Maximum generated tokens.", parsePositiveInt)
|
|
1115
|
-
.option("--context-limit <number>", "Maximum context characters sent to the model.", parsePositiveInt)
|
|
1116
|
-
.option("--json", "Print machine-readable JSON.")
|
|
1117
|
-
.action(async (input, options, command) => {
|
|
1118
|
-
const cwd = projectRoot(command);
|
|
1119
|
-
const chat = await loadChat();
|
|
1120
|
-
const mode = chatMode(input);
|
|
1121
|
-
if (mode === "doctor") {
|
|
1122
|
-
const doctorOptions = { cwd };
|
|
1123
|
-
addOption(doctorOptions, "profile", options.profile);
|
|
1124
|
-
addOption(doctorOptions, "modelPath", options.modelPath);
|
|
1125
|
-
addOption(doctorOptions, "verifyHash", options.verify);
|
|
1126
|
-
const report = await chat.doctor(doctorOptions);
|
|
1127
|
-
printMaybeJson(report, options.json);
|
|
1128
|
-
return;
|
|
1129
|
-
}
|
|
1130
|
-
if (mode === "setup") {
|
|
1131
|
-
const setupOptions = { cwd };
|
|
1132
|
-
addOption(setupOptions, "profile", options.profile);
|
|
1133
|
-
addOption(setupOptions, "modelPath", options.modelPath);
|
|
1134
|
-
addOption(setupOptions, "allowRemoteModels", options.offline ? false : options.allowRemoteModels);
|
|
1135
|
-
const result = await chat.setupChatModel(setupOptions);
|
|
1136
|
-
printMaybeJson(result, options.json);
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
const question = await promptInput(input);
|
|
1140
|
-
if (question.trim().length === 0) {
|
|
1141
|
-
console.error(pc.red('Missing question. Use `rgr chat "your question"`.'));
|
|
1142
|
-
process.exitCode = 1;
|
|
1143
|
-
return;
|
|
1144
|
-
}
|
|
1145
|
-
const sources = await search(question, withTopK(cwd, options.topK));
|
|
1146
|
-
const chatOptions = {
|
|
1147
|
-
cwd,
|
|
1148
|
-
question,
|
|
1149
|
-
sources: sources.map(toChatSource),
|
|
1150
|
-
};
|
|
1151
|
-
addOption(chatOptions, "profile", options.profile);
|
|
1152
|
-
addOption(chatOptions, "thinking", options.thinking);
|
|
1153
|
-
addOption(chatOptions, "modelPath", options.modelPath);
|
|
1154
|
-
addOption(chatOptions, "allowRemoteModels", chatAllowRemoteModels(options));
|
|
1155
|
-
addOption(chatOptions, "maxNewTokens", options.maxNewTokens);
|
|
1156
|
-
addOption(chatOptions, "contextCharLimit", options.contextLimit);
|
|
1157
|
-
const result = await chat.generateChatAnswer(chatOptions);
|
|
1158
|
-
if (options.json) {
|
|
1159
|
-
console.log(JSON.stringify({ query: question, ...result }, null, 2));
|
|
1160
|
-
if (result.emptyContext) {
|
|
1161
|
-
process.exitCode = 1;
|
|
1162
|
-
}
|
|
1163
|
-
return;
|
|
1164
|
-
}
|
|
1165
|
-
console.log(`\n${result.answer}\n`);
|
|
1166
|
-
if (!result.emptyContext && result.citationStatus !== "valid") {
|
|
1167
|
-
console.error(pc.yellow(`Citation status: ${result.citationStatus}. Review the answer against the retrieved passages.`));
|
|
1168
|
-
}
|
|
1169
|
-
if (result.sources.length > 0) {
|
|
1170
|
-
console.log(pc.dim("Sources:"));
|
|
1171
|
-
for (const [index, source] of result.sources.entries()) {
|
|
1172
|
-
console.log(` [${index + 1}] ${source.relativePath} chunk=${source.chunkIndex}`);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
else {
|
|
1176
|
-
const repairCommand = await rgrCommand(cwd, ["doctor", "--fix"]);
|
|
1177
|
-
console.error(pc.yellow(`No Ragmir context found. Run \`${repairCommand.display}\`.`));
|
|
1178
|
-
process.exitCode = 1;
|
|
1179
|
-
}
|
|
1180
|
-
});
|
|
1181
|
-
program
|
|
1182
|
-
.command("audio")
|
|
1183
|
-
.description("Render narration as offline WAV or explicitly selected online Edge MP3.")
|
|
1184
|
-
.argument("[text-file]", "Narration text file to render.")
|
|
1185
|
-
.option("-o, --out <path>", "Output MP3 or WAV path.")
|
|
1186
|
-
.option("--engine <engine>", "TTS engine: auto, edge, or transformers.")
|
|
1187
|
-
.option("--lang <language>", "TTS language. Offline: en, es, fr. Edge also: ja, th, zh. Default: fr.")
|
|
1188
|
-
.option("--model <id>", "Transformers.js TTS model ID.")
|
|
1189
|
-
.option("--model-path <path>", "Local model/cache path.")
|
|
1190
|
-
.option("--offline", "Force the Transformers.js local/offline WAV path.")
|
|
1191
|
-
.option("--allow-remote-models", "Explicitly allow remote model downloads.")
|
|
1192
|
-
.option("--voice <voice>", "Edge voice override. Default matches --lang.")
|
|
1193
|
-
.option("--rate <rate>", "Edge rate. Defaults to +0%.")
|
|
1194
|
-
.option("--speaker-embeddings <path>", "Optional model-specific speaker embedding path or URL.")
|
|
1195
|
-
.option("--speed <number>", "Optional model-specific speech speed.", parseNumber)
|
|
1196
|
-
.option("--doctor", "Show TTS runtime readiness instead of rendering.")
|
|
1197
|
-
.option("--json", "Print machine-readable JSON.")
|
|
1198
|
-
.action(async (textFile, options, command) => {
|
|
1199
|
-
const cwd = projectRoot(command);
|
|
1200
|
-
const tts = await loadTts();
|
|
1201
|
-
if (options.doctor) {
|
|
1202
|
-
const report = await tts.doctor();
|
|
1203
|
-
printMaybeJson(report, options.json);
|
|
1204
|
-
return;
|
|
1205
|
-
}
|
|
1206
|
-
if (!textFile) {
|
|
1207
|
-
console.error(pc.red("Missing text file. Use `rgr audio <text-file>`."));
|
|
1208
|
-
process.exitCode = 1;
|
|
1209
|
-
return;
|
|
1210
|
-
}
|
|
1211
|
-
const renderOptions = {
|
|
1212
|
-
cwd,
|
|
1213
|
-
textFile,
|
|
1214
|
-
engine: audioEngine(options),
|
|
1215
|
-
};
|
|
1216
|
-
addOption(renderOptions, "language", audioLanguage(options));
|
|
1217
|
-
addOption(renderOptions, "outputPath", options.out);
|
|
1218
|
-
addOption(renderOptions, "model", options.model);
|
|
1219
|
-
addOption(renderOptions, "modelPath", options.modelPath);
|
|
1220
|
-
addOption(renderOptions, "allowRemoteModels", audioAllowRemoteModels(options));
|
|
1221
|
-
addOption(renderOptions, "voice", options.voice);
|
|
1222
|
-
addOption(renderOptions, "rate", options.rate);
|
|
1223
|
-
addOption(renderOptions, "speakerEmbeddings", options.speakerEmbeddings);
|
|
1224
|
-
addOption(renderOptions, "speed", options.speed);
|
|
1225
|
-
const result = await tts.renderSpeech(renderOptions);
|
|
1226
|
-
printMaybeJson(result, options.json);
|
|
1227
|
-
});
|
|
1228
866
|
program
|
|
1229
867
|
.command("serve-mcp")
|
|
1230
868
|
.description("Start the MCP server over stdio for Claude, Codex, and other MCP-compatible agents.")
|
|
@@ -1232,65 +870,6 @@ program
|
|
|
1232
870
|
const explicitRoot = explicitProjectRoot(command);
|
|
1233
871
|
await serveMcp(explicitRoot);
|
|
1234
872
|
});
|
|
1235
|
-
const portableCommand = program
|
|
1236
|
-
.command("portable")
|
|
1237
|
-
.description("Export or verify a frozen, relocatable Ragmir knowledge-base folder.");
|
|
1238
|
-
portableCommand
|
|
1239
|
-
.command("export")
|
|
1240
|
-
.description("Export the active index, skills, launcher, and MCP adapters into one folder.")
|
|
1241
|
-
.option("-o, --output <directory>", "Destination directory. Defaults under .ragmir/exports/.")
|
|
1242
|
-
.option("--name <name>", "Portable knowledge-base display name.")
|
|
1243
|
-
.option("--replace", "Replace an existing portable destination after preserving it as a sibling backup.")
|
|
1244
|
-
.option("--json", "Print machine-readable JSON.")
|
|
1245
|
-
.action(async (options, command) => {
|
|
1246
|
-
const exportOptions = {
|
|
1247
|
-
cwd: projectRoot(command),
|
|
1248
|
-
replaceExisting: options.replace === true,
|
|
1249
|
-
};
|
|
1250
|
-
addOption(exportOptions, "outputDir", options.output);
|
|
1251
|
-
addOption(exportOptions, "name", options.name);
|
|
1252
|
-
const result = await exportPortableKnowledgeBase(exportOptions);
|
|
1253
|
-
if (options.json) {
|
|
1254
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
|
-
console.log(pc.green("Portable knowledge base exported."));
|
|
1258
|
-
console.log(`outputDir=${result.outputDir}`);
|
|
1259
|
-
if (result.previousOutputDir) {
|
|
1260
|
-
console.log(`previousOutputDir=${result.previousOutputDir}`);
|
|
1261
|
-
}
|
|
1262
|
-
console.log(`manifestPath=${result.manifestPath}`);
|
|
1263
|
-
console.log(`fileCount=${result.fileCount}`);
|
|
1264
|
-
console.log(`totalBytes=${result.totalBytes}`);
|
|
1265
|
-
console.log(`embeddingModelIncluded=${result.embeddingModelIncluded}`);
|
|
1266
|
-
console.log(result.previousOutputDir
|
|
1267
|
-
? "Next: verify the active destination, restart its consumers, then retire the preserved previous folder when safe."
|
|
1268
|
-
: "Next: move the folder, then run `node bin/rgr.cjs portable verify . --json`.");
|
|
1269
|
-
});
|
|
1270
|
-
portableCommand
|
|
1271
|
-
.command("verify")
|
|
1272
|
-
.description("Verify file integrity, index compatibility, and active table readability.")
|
|
1273
|
-
.argument("[directory]", "Portable knowledge-base directory.", ".")
|
|
1274
|
-
.option("--json", "Print machine-readable JSON.")
|
|
1275
|
-
.action(async (directory, options) => {
|
|
1276
|
-
const result = await verifyPortableKnowledgeBase(directory);
|
|
1277
|
-
if (options.json) {
|
|
1278
|
-
console.log(JSON.stringify(result, null, 2));
|
|
1279
|
-
}
|
|
1280
|
-
else {
|
|
1281
|
-
console.log(result.valid
|
|
1282
|
-
? pc.green("Portable knowledge base is valid.")
|
|
1283
|
-
: pc.red("Portable knowledge base is invalid."));
|
|
1284
|
-
console.log(`root=${result.root}`);
|
|
1285
|
-
console.log(`checkedFiles=${result.checkedFiles}`);
|
|
1286
|
-
for (const warning of result.warnings)
|
|
1287
|
-
console.log(pc.yellow(`warning=${warning}`));
|
|
1288
|
-
for (const error of result.errors)
|
|
1289
|
-
console.log(pc.red(`error=${error}`));
|
|
1290
|
-
}
|
|
1291
|
-
if (!result.valid)
|
|
1292
|
-
process.exitCode = 1;
|
|
1293
|
-
});
|
|
1294
873
|
program
|
|
1295
874
|
.command("skill-path")
|
|
1296
875
|
.description("Print the bundled Ragmir skill path for agents that can load SKILL.md folders.")
|
|
@@ -1324,8 +903,6 @@ program
|
|
|
1324
903
|
console.log(` - ${file}`);
|
|
1325
904
|
}
|
|
1326
905
|
console.log(`Skill path: ${result.skillPath}`);
|
|
1327
|
-
console.log(`Optional audio skill path: ${result.audioSkillPath}`);
|
|
1328
|
-
console.log(`Optional Markdown report skill path: ${result.reportSkillPath}`);
|
|
1329
906
|
console.log(`MCP config example: ${result.mcpConfigPath}`);
|
|
1330
907
|
for (const helper of result.agentHelpers) {
|
|
1331
908
|
console.log(`${helper.label} MCP helper: ${helper.path}`);
|
|
@@ -1395,25 +972,6 @@ function explicitProjectRoot(command) {
|
|
|
1395
972
|
const options = command.optsWithGlobals();
|
|
1396
973
|
return options.projectRoot ? path.resolve(options.projectRoot) : undefined;
|
|
1397
974
|
}
|
|
1398
|
-
function deprecatedCliInvocation() {
|
|
1399
|
-
const invokedPath = process.argv[1];
|
|
1400
|
-
if (!invokedPath)
|
|
1401
|
-
return null;
|
|
1402
|
-
const commandName = path.basename(invokedPath).replace(/\.(?:cmd|ps1)$/iu, "");
|
|
1403
|
-
return DEPRECATED_CLI_NAMES.has(commandName) ? commandName : null;
|
|
1404
|
-
}
|
|
1405
|
-
async function promptInput(promptParts) {
|
|
1406
|
-
if (promptParts !== undefined && promptParts.length > 0) {
|
|
1407
|
-
return promptParts.join(" ");
|
|
1408
|
-
}
|
|
1409
|
-
if (process.stdin.isTTY) {
|
|
1410
|
-
return "";
|
|
1411
|
-
}
|
|
1412
|
-
return readBoundedStdin(process.stdin);
|
|
1413
|
-
}
|
|
1414
|
-
function withTopK(cwd, topK) {
|
|
1415
|
-
return topK === undefined ? { cwd } : { cwd, topK };
|
|
1416
|
-
}
|
|
1417
975
|
function withSearchOptions(cwd, options) {
|
|
1418
976
|
const result = { cwd };
|
|
1419
977
|
addOption(result, "topK", options.topK);
|
|
@@ -1437,89 +995,6 @@ function addPathFilters(target, options) {
|
|
|
1437
995
|
target.contextPaths = options.contextPath;
|
|
1438
996
|
}
|
|
1439
997
|
}
|
|
1440
|
-
async function loadChat() {
|
|
1441
|
-
let module;
|
|
1442
|
-
try {
|
|
1443
|
-
module = await import(CHAT_PACKAGE_NAME);
|
|
1444
|
-
}
|
|
1445
|
-
catch (error) {
|
|
1446
|
-
if (isMissingOptionalPackage(error, CHAT_PACKAGE_NAME)) {
|
|
1447
|
-
throw new Error(`Ragmir Chat is optional and is not installed. Add ${CHAT_PACKAGE_NAME} to this project before using \`rgr chat\`.`);
|
|
1448
|
-
}
|
|
1449
|
-
throw error;
|
|
1450
|
-
}
|
|
1451
|
-
if (!isChatModule(module)) {
|
|
1452
|
-
throw new Error(`${CHAT_PACKAGE_NAME} did not expose the expected chat API.`);
|
|
1453
|
-
}
|
|
1454
|
-
return module;
|
|
1455
|
-
}
|
|
1456
|
-
function isChatModule(value) {
|
|
1457
|
-
return (typeof value === "object" &&
|
|
1458
|
-
value !== null &&
|
|
1459
|
-
"doctor" in value &&
|
|
1460
|
-
typeof value.doctor === "function" &&
|
|
1461
|
-
"generateChatAnswer" in value &&
|
|
1462
|
-
typeof value.generateChatAnswer === "function" &&
|
|
1463
|
-
"setupChatModel" in value &&
|
|
1464
|
-
typeof value.setupChatModel === "function");
|
|
1465
|
-
}
|
|
1466
|
-
function chatMode(input) {
|
|
1467
|
-
if (input?.length === 1 && input[0] === "doctor") {
|
|
1468
|
-
return "doctor";
|
|
1469
|
-
}
|
|
1470
|
-
if (input?.length === 1 && input[0] === "setup") {
|
|
1471
|
-
return "setup";
|
|
1472
|
-
}
|
|
1473
|
-
return "ask";
|
|
1474
|
-
}
|
|
1475
|
-
function chatAllowRemoteModels(options) {
|
|
1476
|
-
if (options.offline) {
|
|
1477
|
-
return false;
|
|
1478
|
-
}
|
|
1479
|
-
if (options.allowRemoteModels) {
|
|
1480
|
-
return true;
|
|
1481
|
-
}
|
|
1482
|
-
return undefined;
|
|
1483
|
-
}
|
|
1484
|
-
function toChatSource(source) {
|
|
1485
|
-
return {
|
|
1486
|
-
source: source.source,
|
|
1487
|
-
relativePath: source.relativePath,
|
|
1488
|
-
chunkIndex: source.chunkIndex,
|
|
1489
|
-
text: source.text,
|
|
1490
|
-
distance: source.distance,
|
|
1491
|
-
};
|
|
1492
|
-
}
|
|
1493
|
-
async function loadTts() {
|
|
1494
|
-
let module;
|
|
1495
|
-
try {
|
|
1496
|
-
module = await import(TTS_PACKAGE_NAME);
|
|
1497
|
-
}
|
|
1498
|
-
catch (error) {
|
|
1499
|
-
if (isMissingOptionalPackage(error, TTS_PACKAGE_NAME)) {
|
|
1500
|
-
throw new Error(`Ragmir TTS is optional and is not installed. Add ${TTS_PACKAGE_NAME} to this project before using \`rgr audio\`.`);
|
|
1501
|
-
}
|
|
1502
|
-
throw error;
|
|
1503
|
-
}
|
|
1504
|
-
if (!isTtsModule(module)) {
|
|
1505
|
-
throw new Error(`${TTS_PACKAGE_NAME} did not expose the expected TTS API.`);
|
|
1506
|
-
}
|
|
1507
|
-
return module;
|
|
1508
|
-
}
|
|
1509
|
-
function isMissingOptionalPackage(error, packageName) {
|
|
1510
|
-
return (error instanceof Error &&
|
|
1511
|
-
"code" in error &&
|
|
1512
|
-
error.code === "ERR_MODULE_NOT_FOUND" &&
|
|
1513
|
-
error.message.includes(packageName));
|
|
1514
|
-
}
|
|
1515
|
-
function isTtsModule(value) {
|
|
1516
|
-
return (typeof value === "object" &&
|
|
1517
|
-
value !== null &&
|
|
1518
|
-
"doctor" in value &&
|
|
1519
|
-
typeof value.doctor === "function" &&
|
|
1520
|
-
"renderSpeech" in value &&
|
|
1521
|
-
typeof value.renderSpeech === "function");
|
|
1522
|
-
}
|
|
1523
998
|
function printDoctor(report) {
|
|
1524
999
|
console.log(`mode=${report.mode}`);
|
|
1525
1000
|
console.log(`cost=${report.cost}`);
|
|
@@ -1551,8 +1026,6 @@ function printDoctor(report) {
|
|
|
1551
1026
|
}
|
|
1552
1027
|
console.log(`embeddingProvider=${report.embeddingProvider}`);
|
|
1553
1028
|
console.log(`transformersAllowRemoteModels=${report.transformersAllowRemoteModels}`);
|
|
1554
|
-
console.log(`redactionEnabled=${report.redactionEnabled}`);
|
|
1555
|
-
console.log(`accessLog=${report.accessLog}`);
|
|
1556
1029
|
console.log(`supportedFiles=${report.supportedFiles}`);
|
|
1557
1030
|
console.log(`supportedBytes=${report.supportedBytes}`);
|
|
1558
1031
|
console.log(`largestFileBytes=${report.largestFileBytes}`);
|
|
@@ -1633,148 +1106,7 @@ function printGenerationGarbageCollection(report) {
|
|
|
1633
1106
|
console.log(pc.yellow(`warning: ${report.warning}`));
|
|
1634
1107
|
}
|
|
1635
1108
|
}
|
|
1636
|
-
function printResearchReport(report) {
|
|
1637
|
-
console.log(`query=${report.query}`);
|
|
1638
|
-
console.log(`ready=${report.ready}`);
|
|
1639
|
-
console.log(`generatedQueries=${report.generatedQueries.length}`);
|
|
1640
|
-
console.log(`audit.mode=${report.audit.mode} audit.inventoryVerified=${report.audit.inventoryVerified} audit.supportedFiles=${report.audit.supportedFiles} audit.supportedBytes=${report.audit.supportedBytes} audit.largestFileBytes=${report.audit.largestFileBytes} audit.indexedFiles=${report.audit.indexedFiles} audit.totalChunks=${report.audit.totalChunks} audit.skippedFiles=${report.audit.skippedFiles} audit.oversizedFiles=${report.audit.oversizedFiles} audit.missingFromIndex=${report.audit.missingFromIndex} audit.staleInIndex=${report.audit.staleInIndex}`);
|
|
1641
|
-
console.log(`budgets.timeoutMs=${report.budgets.timeoutMs ?? "none"} budgets.evidenceTopK=${report.budgets.evidenceTopK} budgets.codeEvidenceTopK=${report.budgets.codeEvidenceTopK} budgets.codeFiles=${report.budgets.codeFilesScanned}/${report.budgets.codeScanMaxFiles} budgets.codeBytes=${report.budgets.codeBytesScanned}/${report.budgets.codeScanMaxBytes} budgets.codeConcurrency=${report.budgets.codeScanConcurrency} budgets.codeTruncated=${report.budgets.codeScanTruncated}`);
|
|
1642
|
-
console.log(`securityWarnings=${report.securityWarnings.length}`);
|
|
1643
|
-
console.log(`sourceDiagnostics.duplicates=${report.sourceDiagnostics.duplicateCandidates.length} sourceDiagnostics.archives=${report.sourceDiagnostics.archiveCandidates.length} sourceDiagnostics.mirrors=${report.sourceDiagnostics.mirrorCandidates.length}`);
|
|
1644
|
-
if (report.sourceDiagnostics.duplicateCandidates.length > 0) {
|
|
1645
|
-
console.log("");
|
|
1646
|
-
console.log(pc.cyan("Duplicate Candidates:"));
|
|
1647
|
-
for (const candidate of report.sourceDiagnostics.duplicateCandidates.slice(0, 5)) {
|
|
1648
|
-
console.log(` - ${candidate.key}: ${candidate.files.join(", ")}`);
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
if (report.evidence.length > 0) {
|
|
1652
|
-
console.log("");
|
|
1653
|
-
console.log(pc.cyan("Evidence:"));
|
|
1654
|
-
for (const [index, evidence] of report.evidence.entries()) {
|
|
1655
|
-
const distance = evidence.distance === null ? "n/a" : evidence.distance.toFixed(4);
|
|
1656
|
-
console.log(` [${index + 1}] ${evidence.relativePath} chunk=${evidence.chunkIndex} distance=${distance} researchScore=${evidence.researchScore.toFixed(6)} bestRank=${evidence.bestRank}`);
|
|
1657
|
-
console.log(` ${researchEvidencePreview(evidence)}`);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
if (report.codeEvidence.length > 0) {
|
|
1661
|
-
console.log("");
|
|
1662
|
-
console.log(pc.cyan("Code Evidence:"));
|
|
1663
|
-
for (const evidence of report.codeEvidence.slice(0, 10)) {
|
|
1664
|
-
console.log(` - ${evidence.relativePath}:${evidence.lineNumber} score=${evidence.score} terms=${evidence.matchedTerms.join(",")}`);
|
|
1665
|
-
console.log(` ${evidence.snippet}`);
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
if (report.gaps.length > 0) {
|
|
1669
|
-
console.log("");
|
|
1670
|
-
console.log(pc.yellow("Gaps:"));
|
|
1671
|
-
for (const gap of report.gaps) {
|
|
1672
|
-
console.log(pc.yellow(` - ${gap}`));
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
console.log("");
|
|
1676
|
-
console.log(pc.cyan("Next Steps:"));
|
|
1677
|
-
for (const step of report.nextSteps) {
|
|
1678
|
-
console.log(` - ${step}`);
|
|
1679
|
-
}
|
|
1680
|
-
}
|
|
1681
|
-
function researchEvidencePreview(evidence) {
|
|
1682
|
-
if ("snippet" in evidence) {
|
|
1683
|
-
return evidence.snippet;
|
|
1684
|
-
}
|
|
1685
|
-
return evidence.text.replace(/\s+/gu, " ").trim().slice(0, SEARCH_TEXT_PREVIEW_LENGTH);
|
|
1686
|
-
}
|
|
1687
|
-
function printTeamComparison(comparison) {
|
|
1688
|
-
const statusColor = comparison.synchronized ? pc.green : pc.yellow;
|
|
1689
|
-
console.log(statusColor(`Team status: ${comparison.status}`));
|
|
1690
|
-
console.log(`summary=${comparison.summary}`);
|
|
1691
|
-
console.log(`local=${comparison.localLabel}`);
|
|
1692
|
-
console.log(`peer=${comparison.peerLabel}`);
|
|
1693
|
-
console.log(`localSecurityAdvisories=${comparison.securityAdvisories.local}`);
|
|
1694
|
-
console.log(`peerSecurityAdvisories=${comparison.securityAdvisories.peer}`);
|
|
1695
|
-
console.log(`sameConfiguration=${comparison.sameConfiguration}`);
|
|
1696
|
-
console.log(`sameCorpus=${comparison.sameCorpus}`);
|
|
1697
|
-
console.log(`authorityDecisionRequired=${comparison.authorityDecisionRequired}`);
|
|
1698
|
-
if (comparison.configurationDifferences.length > 0) {
|
|
1699
|
-
console.log("");
|
|
1700
|
-
console.log(pc.cyan("Configuration differences:"));
|
|
1701
|
-
for (const difference of comparison.configurationDifferences) {
|
|
1702
|
-
console.log(` - ${difference.field} (${difference.scope}, rebuild=${difference.requiresRebuild}): local=${formatTeamValue(difference.local)} peer=${formatTeamValue(difference.peer)}`);
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
|
-
printTeamPaths("Local-only files", comparison.files.localOnly);
|
|
1706
|
-
printTeamPaths("Peer-only files", comparison.files.peerOnly);
|
|
1707
|
-
if (comparison.files.changed.length > 0) {
|
|
1708
|
-
console.log("");
|
|
1709
|
-
console.log(pc.cyan(`Changed files (${comparison.files.changed.length}):`));
|
|
1710
|
-
for (const file of comparison.files.changed.slice(0, TEAM_DIFF_PREVIEW_LIMIT)) {
|
|
1711
|
-
console.log(` - ${file.relativePath} local=${file.localChecksum.slice(0, 12)} peer=${file.peerChecksum.slice(0, 12)}`);
|
|
1712
|
-
}
|
|
1713
|
-
printTeamOmitted(comparison.files.changed.length);
|
|
1714
|
-
}
|
|
1715
|
-
if (comparison.recommendedActions.length > 0) {
|
|
1716
|
-
console.log("");
|
|
1717
|
-
console.log(pc.cyan("Recommended actions:"));
|
|
1718
|
-
for (const [index, action] of comparison.recommendedActions.entries()) {
|
|
1719
|
-
console.log(` ${index + 1}. ${action}`);
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
function printTeamSync(report) {
|
|
1724
|
-
const statusColor = report.synchronized
|
|
1725
|
-
? pc.green
|
|
1726
|
-
: report.status === "index-not-ready"
|
|
1727
|
-
? pc.red
|
|
1728
|
-
: pc.yellow;
|
|
1729
|
-
console.log(statusColor(`Team sync: ${report.status}`));
|
|
1730
|
-
console.log(`summary=${report.summary}`);
|
|
1731
|
-
console.log(`gitState=${report.git.state}`);
|
|
1732
|
-
console.log(`branch=${report.git.branch ?? "none"}`);
|
|
1733
|
-
console.log(`upstream=${report.git.upstream ?? "none"}`);
|
|
1734
|
-
console.log(`ahead=${report.git.ahead ?? "unknown"}`);
|
|
1735
|
-
console.log(`behind=${report.git.behind ?? "unknown"}`);
|
|
1736
|
-
console.log(`dirty=${report.git.dirty ?? "unknown"}`);
|
|
1737
|
-
console.log(`fetched=${report.git.fetched}`);
|
|
1738
|
-
console.log(`updated=${report.git.updated}`);
|
|
1739
|
-
console.log(`indexReady=${report.index.operationalReady && report.index.indexPolicyCurrent}`);
|
|
1740
|
-
console.log(`indexedFiles=${report.index.indexedFiles}`);
|
|
1741
|
-
console.log(`chunksIndexed=${report.index.chunksIndexed}`);
|
|
1742
|
-
console.log(`securityAdvisories=${report.index.securityAdvisories}`);
|
|
1743
|
-
if (report.warnings.length > 0) {
|
|
1744
|
-
console.log("");
|
|
1745
|
-
console.log(pc.yellow("Warnings:"));
|
|
1746
|
-
for (const warning of report.warnings) {
|
|
1747
|
-
console.log(` - ${warning}`);
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
if (report.recommendedActions.length > 0) {
|
|
1751
|
-
console.log("");
|
|
1752
|
-
console.log(pc.cyan("Next action:"));
|
|
1753
|
-
console.log(` ${report.recommendedActions[0]}`);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
function printTeamPaths(title, files) {
|
|
1757
|
-
if (files.length === 0) {
|
|
1758
|
-
return;
|
|
1759
|
-
}
|
|
1760
|
-
console.log("");
|
|
1761
|
-
console.log(pc.cyan(`${title} (${files.length}):`));
|
|
1762
|
-
for (const file of files.slice(0, TEAM_DIFF_PREVIEW_LIMIT)) {
|
|
1763
|
-
console.log(` - ${file}`);
|
|
1764
|
-
}
|
|
1765
|
-
printTeamOmitted(files.length);
|
|
1766
|
-
}
|
|
1767
|
-
function printTeamOmitted(total) {
|
|
1768
|
-
const omitted = total - TEAM_DIFF_PREVIEW_LIMIT;
|
|
1769
|
-
if (omitted > 0) {
|
|
1770
|
-
console.log(` ... ${omitted} more; use --json for the complete diff.`);
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
function formatTeamValue(value) {
|
|
1774
|
-
return Array.isArray(value) ? JSON.stringify(value) : String(value);
|
|
1775
|
-
}
|
|
1776
1109
|
function printPdfOcrStatus(status) {
|
|
1777
|
-
console.log(`privacyProfile=${status.privacyProfile}`);
|
|
1778
1110
|
console.log(`configured=${status.configured}`);
|
|
1779
1111
|
console.log(`recommendedEngine=${status.recommendedEngine ?? "none"}`);
|
|
1780
1112
|
console.log(`ocrmypdf.available=${status.ocrmypdf.available}`);
|
|
@@ -1785,15 +1117,6 @@ function printPdfOcrStatus(status) {
|
|
|
1785
1117
|
console.log(`pdftoppm.available=${status.pdftoppm.available}`);
|
|
1786
1118
|
console.log(`pdftoppm.version=${status.pdftoppm.version ?? "unavailable"}`);
|
|
1787
1119
|
console.log(`languages=${status.languages.join(",")}`);
|
|
1788
|
-
if (status.privacyProfile === "strict") {
|
|
1789
|
-
console.log(pc.yellow("The strict privacy profile disables external OCR even when local tools are installed."));
|
|
1790
|
-
}
|
|
1791
|
-
else if (!status.recommendedEngine) {
|
|
1792
|
-
console.log(pc.yellow("Install OCRmyPDF 12.6+ or install both Tesseract and Poppler, then run `rgr ocr setup`."));
|
|
1793
|
-
}
|
|
1794
|
-
else if (!status.configured) {
|
|
1795
|
-
console.log(`Run \`rgr ocr setup --engine ${status.recommendedEngine}\` to enable local PDF OCR.`);
|
|
1796
|
-
}
|
|
1797
1120
|
}
|
|
1798
1121
|
function printSetup(result, title) {
|
|
1799
1122
|
console.log(pc.green(title));
|
|
@@ -1813,8 +1136,6 @@ function printSetup(result, title) {
|
|
|
1813
1136
|
console.log("");
|
|
1814
1137
|
console.log(pc.cyan("Agent integration:"));
|
|
1815
1138
|
console.log(` - skill: ${result.agentKit.skillPath}`);
|
|
1816
|
-
console.log(` - audio skill: ${result.agentKit.audioSkillPath}`);
|
|
1817
|
-
console.log(` - report skill: ${result.agentKit.reportSkillPath}`);
|
|
1818
1139
|
console.log(` - MCP config: ${result.agentKit.mcpConfigPath}`);
|
|
1819
1140
|
for (const helper of result.agentKit.agentHelpers) {
|
|
1820
1141
|
console.log(` - ${helper.label} MCP helper: ${helper.path}`);
|
|
@@ -1878,19 +1199,6 @@ function printEmptyTextFiles(files) {
|
|
|
1878
1199
|
}
|
|
1879
1200
|
console.log(pc.yellow("These supported files produced no indexable text. For scanned PDFs, run `rgr ocr doctor` then `rgr ocr setup`; for images, configure imageOcrCommand or store local OCR text beside the source file."));
|
|
1880
1201
|
}
|
|
1881
|
-
function printMaybeJson(value, json) {
|
|
1882
|
-
if (json) {
|
|
1883
|
-
console.log(JSON.stringify(value, null, 2));
|
|
1884
|
-
return;
|
|
1885
|
-
}
|
|
1886
|
-
if (typeof value === "object" && value !== null) {
|
|
1887
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
1888
|
-
console.log(`${key}=${String(entry)}`);
|
|
1889
|
-
}
|
|
1890
|
-
return;
|
|
1891
|
-
}
|
|
1892
|
-
console.log(String(value));
|
|
1893
|
-
}
|
|
1894
1202
|
function addOption(target, key, value) {
|
|
1895
1203
|
if (value !== undefined) {
|
|
1896
1204
|
target[key] = value;
|