Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 35 additions & 18 deletions src/cli/cli_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ USAGE
vectis --help Show this text.

DIGEST OPTIONS
--format json | slim | md Output format (default: slim).
`slim` is structure-only and the
most token-efficient for agent
context. `json` adds hotspot body
excerpts; `md` is human-readable.
--format json | slim Output format (default: slim).
Both are JSON; `slim` is the
token-efficient agent default,
`json` adds per-file symbols and
hotspot body excerpts.
--output <file> Write to <file>. Use '-' for stdout
(default: stdout).
--cache Reuse SQLite state between runs at
Expand All @@ -74,7 +74,7 @@ EXIT CODES
EXAMPLES
vectis digest ./my-project # Slim JSON to stdout
vectis digest ./my-project --format json # Full JSON with excerpts
vectis digest ./my-project --cache --format md # Cached, markdown
vectis digest ./my-project --cache # Cached slim JSON
vectis digest . --cache-dir /tmp/vc --format slim # Custom cache dir
vectis mcp # MCP server on stdio
)";
Expand All @@ -84,6 +84,27 @@ void print_usage()
std::fputs(k_usage, stdout);
}

/// Render a count with its singular or plural form, e.g. `1 file` vs
/// `2 files`. Used to keep the `-v` summary line grammatical for the
/// 1-file / 1-dep edge cases.
[[nodiscard]] std::string count_word(std::size_t n, const char* singular, const char* plural)
{
return std::to_string(n) + ' ' + (n == 1 ? singular : plural);
}

/// Format the `vectis: scanned …` verbose summary line written to
/// stderr after a successful scan. Single source of truth so the two
/// CLI entry points (digest, explain) emit identical text.
[[nodiscard]] std::string scan_summary_line(std::size_t files, std::uint64_t files_skipped,
std::size_t symbols, std::size_t deps,
std::int64_t elapsed_ms)
{
return "vectis: scanned " + count_word(files, "file", "files") + " (" +
std::to_string(files_skipped) + " skipped), " +
count_word(symbols, "symbol", "symbols") + ", " + count_word(deps, "dep", "deps") +
" in " + std::to_string(elapsed_ms) + " ms\n";
}

/// Parse `--format` value. Returns false on unknown value.
bool parse_format(std::string_view v, vectis::code::DigestFormat& out)
{
Expand All @@ -96,10 +117,6 @@ bool parse_format(std::string_view v, vectis::code::DigestFormat& out)
out = DigestFormat::SlimJson;
return true;
}
if (v == "md" || v == "markdown") {
out = DigestFormat::Markdown;
return true;
}
return false;
}

Expand Down Expand Up @@ -425,10 +442,10 @@ prepare_and_run_scan(const std::filesystem::path& project_root, bool use_cache,
const auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - t_start)
.count();
std::fprintf(
stderr, "vectis: scanned %zu files (%llu skipped), %zu symbols, %zu deps in %lld ms\n",
index.file_count(), static_cast<unsigned long long>(scan->files_skipped),
index.symbol_count(), index.dependency_count(), static_cast<long long>(elapsed_ms));
const std::string line =
scan_summary_line(index.file_count(), scan->files_skipped, index.symbol_count(),
index.dependency_count(), static_cast<std::int64_t>(elapsed_ms));
std::fputs(line.c_str(), stderr);
}

vectis::code::ExplainOptions explain_opts;
Expand Down Expand Up @@ -470,10 +487,10 @@ int run_explain(const ExplainArgs& args)
const auto elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - t_start)
.count();
std::fprintf(
stderr, "vectis: scanned %zu files (%llu skipped), %zu symbols, %zu deps in %lld ms\n",
index.file_count(), static_cast<unsigned long long>(scan->files_skipped),
index.symbol_count(), index.dependency_count(), static_cast<long long>(elapsed_ms));
const std::string line =
scan_summary_line(index.file_count(), scan->files_skipped, index.symbol_count(),
index.dependency_count(), static_cast<std::int64_t>(elapsed_ms));
std::fputs(line.c_str(), stderr);
}

vectis::code::ExportOptions export_opts;
Expand Down
Loading
Loading