vemora 0.1.0-alpha.8
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 +716 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +589 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ask.d.ts +14 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +136 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/audit.d.ts +17 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +408 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/brief.d.ts +14 -0
- package/dist/commands/brief.d.ts.map +1 -0
- package/dist/commands/brief.js +73 -0
- package/dist/commands/brief.js.map +1 -0
- package/dist/commands/chat.d.ts +7 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +161 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/context.d.ts +61 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +778 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/deps.d.ts +20 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +138 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/focus.d.ts +6 -0
- package/dist/commands/focus.d.ts.map +1 -0
- package/dist/commands/focus.js +302 -0
- package/dist/commands/focus.js.map +1 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +366 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init-agent.d.ts +23 -0
- package/dist/commands/init-agent.d.ts.map +1 -0
- package/dist/commands/init-agent.js +447 -0
- package/dist/commands/init-agent.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +122 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +98 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/plan.d.ts +16 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +535 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/query.d.ts +39 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +389 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/remember.d.ts +11 -0
- package/dist/commands/remember.d.ts.map +1 -0
- package/dist/commands/remember.js +174 -0
- package/dist/commands/remember.js.map +1 -0
- package/dist/commands/report.d.ts +10 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +180 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +127 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/summarize.d.ts +14 -0
- package/dist/commands/summarize.d.ts.map +1 -0
- package/dist/commands/summarize.js +205 -0
- package/dist/commands/summarize.js.map +1 -0
- package/dist/commands/triage.d.ts +33 -0
- package/dist/commands/triage.d.ts.map +1 -0
- package/dist/commands/triage.js +419 -0
- package/dist/commands/triage.js.map +1 -0
- package/dist/commands/usages.d.ts +14 -0
- package/dist/commands/usages.d.ts.map +1 -0
- package/dist/commands/usages.js +236 -0
- package/dist/commands/usages.js.map +1 -0
- package/dist/core/config.d.ts +35 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +140 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/types.d.ts +251 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/embeddings/factory.d.ts +9 -0
- package/dist/embeddings/factory.d.ts.map +1 -0
- package/dist/embeddings/factory.js +26 -0
- package/dist/embeddings/factory.js.map +1 -0
- package/dist/embeddings/noop.d.ts +17 -0
- package/dist/embeddings/noop.d.ts.map +1 -0
- package/dist/embeddings/noop.js +22 -0
- package/dist/embeddings/noop.js.map +1 -0
- package/dist/embeddings/ollama.d.ts +16 -0
- package/dist/embeddings/ollama.d.ts.map +1 -0
- package/dist/embeddings/ollama.js +41 -0
- package/dist/embeddings/ollama.js.map +1 -0
- package/dist/embeddings/openai.d.ts +10 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +67 -0
- package/dist/embeddings/openai.js.map +1 -0
- package/dist/embeddings/provider.d.ts +19 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +3 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/indexer/callgraph.d.ts +16 -0
- package/dist/indexer/callgraph.d.ts.map +1 -0
- package/dist/indexer/callgraph.js +154 -0
- package/dist/indexer/callgraph.js.map +1 -0
- package/dist/indexer/chunkBySlidingWindow.d.ts +6 -0
- package/dist/indexer/chunkBySlidingWindow.d.ts.map +1 -0
- package/dist/indexer/chunkBySlidingWindow.js +30 -0
- package/dist/indexer/chunkBySlidingWindow.js.map +1 -0
- package/dist/indexer/chunkBySymbols.d.ts +7 -0
- package/dist/indexer/chunkBySymbols.d.ts.map +1 -0
- package/dist/indexer/chunkBySymbols.js +57 -0
- package/dist/indexer/chunkBySymbols.js.map +1 -0
- package/dist/indexer/chunker.d.ts +15 -0
- package/dist/indexer/chunker.d.ts.map +1 -0
- package/dist/indexer/chunker.js +26 -0
- package/dist/indexer/chunker.js.map +1 -0
- package/dist/indexer/classHeader.d.ts +7 -0
- package/dist/indexer/classHeader.d.ts.map +1 -0
- package/dist/indexer/classHeader.js +37 -0
- package/dist/indexer/classHeader.js.map +1 -0
- package/dist/indexer/deps.d.ts +66 -0
- package/dist/indexer/deps.d.ts.map +1 -0
- package/dist/indexer/deps.js +409 -0
- package/dist/indexer/deps.js.map +1 -0
- package/dist/indexer/hasher.d.ts +17 -0
- package/dist/indexer/hasher.d.ts.map +1 -0
- package/dist/indexer/hasher.js +38 -0
- package/dist/indexer/hasher.js.map +1 -0
- package/dist/indexer/parser.d.ts +18 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +355 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/scanner.d.ts +18 -0
- package/dist/indexer/scanner.d.ts.map +1 -0
- package/dist/indexer/scanner.js +37 -0
- package/dist/indexer/scanner.js.map +1 -0
- package/dist/indexer/strategy.d.ts +11 -0
- package/dist/indexer/strategy.d.ts.map +1 -0
- package/dist/indexer/strategy.js +15 -0
- package/dist/indexer/strategy.js.map +1 -0
- package/dist/indexer/tests.d.ts +15 -0
- package/dist/indexer/tests.d.ts.map +1 -0
- package/dist/indexer/tests.js +68 -0
- package/dist/indexer/tests.js.map +1 -0
- package/dist/indexer/todos.d.ts +9 -0
- package/dist/indexer/todos.d.ts.map +1 -0
- package/dist/indexer/todos.js +29 -0
- package/dist/indexer/todos.js.map +1 -0
- package/dist/llm/anthropic.d.ts +8 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +76 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/factory.d.ts +7 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +39 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/ollama.d.ts +8 -0
- package/dist/llm/ollama.d.ts.map +1 -0
- package/dist/llm/ollama.js +83 -0
- package/dist/llm/ollama.js.map +1 -0
- package/dist/llm/openai.d.ts +8 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +68 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +29 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +3 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/search/bm25.d.ts +3 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +102 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/formatter.d.ts +43 -0
- package/dist/search/formatter.d.ts.map +1 -0
- package/dist/search/formatter.js +208 -0
- package/dist/search/formatter.js.map +1 -0
- package/dist/search/hybrid.d.ts +10 -0
- package/dist/search/hybrid.d.ts.map +1 -0
- package/dist/search/hybrid.js +53 -0
- package/dist/search/hybrid.js.map +1 -0
- package/dist/search/merge.d.ts +33 -0
- package/dist/search/merge.d.ts.map +1 -0
- package/dist/search/merge.js +158 -0
- package/dist/search/merge.js.map +1 -0
- package/dist/search/mmr.d.ts +23 -0
- package/dist/search/mmr.d.ts.map +1 -0
- package/dist/search/mmr.js +95 -0
- package/dist/search/mmr.js.map +1 -0
- package/dist/search/rerank.d.ts +15 -0
- package/dist/search/rerank.d.ts.map +1 -0
- package/dist/search/rerank.js +76 -0
- package/dist/search/rerank.js.map +1 -0
- package/dist/search/signature.d.ts +42 -0
- package/dist/search/signature.d.ts.map +1 -0
- package/dist/search/signature.js +112 -0
- package/dist/search/signature.js.map +1 -0
- package/dist/search/vector.d.ts +41 -0
- package/dist/search/vector.d.ts.map +1 -0
- package/dist/search/vector.js +185 -0
- package/dist/search/vector.js.map +1 -0
- package/dist/storage/cache.d.ts +30 -0
- package/dist/storage/cache.d.ts.map +1 -0
- package/dist/storage/cache.js +160 -0
- package/dist/storage/cache.js.map +1 -0
- package/dist/storage/knowledge.d.ts +17 -0
- package/dist/storage/knowledge.d.ts.map +1 -0
- package/dist/storage/knowledge.js +58 -0
- package/dist/storage/knowledge.js.map +1 -0
- package/dist/storage/repository.d.ts +27 -0
- package/dist/storage/repository.d.ts.map +1 -0
- package/dist/storage/repository.js +95 -0
- package/dist/storage/repository.js.map +1 -0
- package/dist/storage/session.d.ts +38 -0
- package/dist/storage/session.d.ts.map +1 -0
- package/dist/storage/session.js +100 -0
- package/dist/storage/session.js.map +1 -0
- package/dist/storage/summaries.d.ts +19 -0
- package/dist/storage/summaries.d.ts.map +1 -0
- package/dist/storage/summaries.js +66 -0
- package/dist/storage/summaries.js.map +1 -0
- package/dist/storage/usage.d.ts +35 -0
- package/dist/storage/usage.d.ts.map +1 -0
- package/dist/storage/usage.js +55 -0
- package/dist/storage/usage.js.map +1 -0
- package/dist/utils/git.d.ts +15 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +38 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/tokenizer.d.ts +24 -0
- package/dist/utils/tokenizer.d.ts.map +1 -0
- package/dist/utils/tokenizer.js +52 -0
- package/dist/utils/tokenizer.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AskOptions {
|
|
2
|
+
/** Number of code chunks to retrieve (default: 5) */
|
|
3
|
+
topK?: number;
|
|
4
|
+
/** Force keyword/BM25 search, skip embeddings */
|
|
5
|
+
keyword?: boolean;
|
|
6
|
+
/** Use hybrid vector+BM25 search */
|
|
7
|
+
hybrid?: boolean;
|
|
8
|
+
/** Max tokens for retrieved context (default: 6000) */
|
|
9
|
+
budget?: number;
|
|
10
|
+
/** Print the retrieved context before the answer */
|
|
11
|
+
showContext?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function runAsk(rootDir: string, question: string, options?: AskOptions): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAQD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAkKf"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runAsk = runAsk;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const config_1 = require("../core/config");
|
|
10
|
+
const factory_1 = require("../embeddings/factory");
|
|
11
|
+
const factory_2 = require("../llm/factory");
|
|
12
|
+
const bm25_1 = require("../search/bm25");
|
|
13
|
+
const hybrid_1 = require("../search/hybrid");
|
|
14
|
+
const vector_1 = require("../search/vector");
|
|
15
|
+
const cache_1 = require("../storage/cache");
|
|
16
|
+
const knowledge_1 = require("../storage/knowledge");
|
|
17
|
+
const repository_1 = require("../storage/repository");
|
|
18
|
+
const summaries_1 = require("../storage/summaries");
|
|
19
|
+
const tokenizer_1 = require("../utils/tokenizer");
|
|
20
|
+
const context_1 = require("./context");
|
|
21
|
+
const SYSTEM_PROMPT = "You are an expert software engineer assistant. " +
|
|
22
|
+
"Answer the user's question accurately and concisely based on the code context provided. " +
|
|
23
|
+
"Reference specific files and symbols when relevant. " +
|
|
24
|
+
"If the context does not contain enough information to answer, say so clearly.";
|
|
25
|
+
async function runAsk(rootDir, question, options = {}) {
|
|
26
|
+
const config = (0, config_1.loadConfig)(rootDir);
|
|
27
|
+
if (!config.summarization) {
|
|
28
|
+
console.error(chalk_1.default.red('No LLM configured. Add a "summarization" block to .vemora/config.json.\n\n' +
|
|
29
|
+
" Example for Ollama:\n" +
|
|
30
|
+
' "summarization": { "provider": "ollama", "model": "qwen2.5-coder:14b" }\n\n' +
|
|
31
|
+
" Example for OpenAI:\n" +
|
|
32
|
+
' "summarization": { "provider": "openai", "model": "gpt-4o-mini" }'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const repo = new repository_1.RepositoryStorage(rootDir);
|
|
36
|
+
const cacheStorage = new cache_1.EmbeddingCacheStorage(config.projectId);
|
|
37
|
+
const summaryStorage = new summaries_1.SummaryStorage(rootDir);
|
|
38
|
+
const topK = options.topK ?? 5;
|
|
39
|
+
const budget = options.budget ?? 6000;
|
|
40
|
+
const chunks = repo.loadChunks();
|
|
41
|
+
const symbols = repo.loadSymbols();
|
|
42
|
+
const depGraph = repo.loadDeps();
|
|
43
|
+
const callGraph = repo.loadCallGraph();
|
|
44
|
+
const fileSummaries = summaryStorage.hasFileSummaries()
|
|
45
|
+
? summaryStorage.loadFileSummaries()
|
|
46
|
+
: {};
|
|
47
|
+
const projectSummary = summaryStorage.loadProjectSummary();
|
|
48
|
+
const knowledgeEntries = new knowledge_1.KnowledgeStorage(rootDir).load();
|
|
49
|
+
if (chunks.length === 0) {
|
|
50
|
+
console.error(chalk_1.default.red("No index found. Run `vemora index` first."));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
// ── Retrieve context ──────────────────────────────────────────────────────
|
|
54
|
+
let results = [];
|
|
55
|
+
const forceKeyword = options.keyword || config.embedding.provider === "none";
|
|
56
|
+
if (forceKeyword && !options.hybrid) {
|
|
57
|
+
results = (0, bm25_1.computeBM25Scores)(question, chunks, symbols, topK);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const spinner = (0, ora_1.default)("Retrieving context...").start();
|
|
61
|
+
try {
|
|
62
|
+
const cache = cacheStorage.load();
|
|
63
|
+
const cachedCount = cache
|
|
64
|
+
? (cache.chunkIds?.length ??
|
|
65
|
+
Object.keys(cache.embeddings ?? {}).length)
|
|
66
|
+
: 0;
|
|
67
|
+
if (!cache || cachedCount === 0) {
|
|
68
|
+
spinner.warn("No embeddings found — falling back to keyword search.");
|
|
69
|
+
results = (0, bm25_1.computeBM25Scores)(question, chunks, symbols, topK);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const provider = (0, factory_1.createEmbeddingProvider)(config.embedding);
|
|
73
|
+
const [queryEmbedding] = await provider.embed([question]);
|
|
74
|
+
if (options.hybrid) {
|
|
75
|
+
results = await (0, hybrid_1.hybridSearch)(question, queryEmbedding, chunks, cache, symbols, { topK });
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
results = (0, vector_1.vectorSearch)(queryEmbedding, chunks, cache, symbols, topK);
|
|
79
|
+
if (results.length === 0) {
|
|
80
|
+
results = (0, bm25_1.computeBM25Scores)(question, chunks, symbols, topK);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
spinner.succeed("Context retrieved");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
spinner.fail(`Search failed: ${err.message}`);
|
|
88
|
+
results = (0, bm25_1.computeBM25Scores)(question, chunks, symbols, topK);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
results = (0, tokenizer_1.applyTokenBudget)(results, budget);
|
|
92
|
+
// ── Build context string ──────────────────────────────────────────────────
|
|
93
|
+
const contextFormat = config.display?.format === "terse" ? "terse" : "plain";
|
|
94
|
+
const contextStr = (0, context_1.generateContextString)(config, results, depGraph, callGraph, fileSummaries, projectSummary?.overview ?? null, { query: question, format: contextFormat }, rootDir, chunks, knowledgeEntries);
|
|
95
|
+
if (options.showContext) {
|
|
96
|
+
console.log(chalk_1.default.gray("─── Retrieved Context ──────────────────────────"));
|
|
97
|
+
console.log(chalk_1.default.gray(contextStr));
|
|
98
|
+
console.log(chalk_1.default.gray("────────────────────────────────────────────────\n"));
|
|
99
|
+
}
|
|
100
|
+
// ── Call LLM ──────────────────────────────────────────────────────────────
|
|
101
|
+
const llmConfig = {
|
|
102
|
+
...config.summarization,
|
|
103
|
+
model: config.summarization.model ?? "gpt-4o-mini",
|
|
104
|
+
};
|
|
105
|
+
const llm = (0, factory_2.createLLMProvider)(llmConfig);
|
|
106
|
+
console.log(chalk_1.default.gray(`\n[${llm.name} · ${llmConfig.model}]\n`));
|
|
107
|
+
let tokensWritten = 0;
|
|
108
|
+
try {
|
|
109
|
+
const response = await llm.chat([
|
|
110
|
+
{
|
|
111
|
+
role: "system",
|
|
112
|
+
content: `${SYSTEM_PROMPT}\n\n${contextStr}`,
|
|
113
|
+
},
|
|
114
|
+
{ role: "user", content: question },
|
|
115
|
+
], {
|
|
116
|
+
stream: true,
|
|
117
|
+
onToken: (token) => {
|
|
118
|
+
process.stdout.write(token);
|
|
119
|
+
tokensWritten++;
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
// Fallback: if provider doesn't support streaming, print the full response.
|
|
123
|
+
if (tokensWritten === 0 && response.content) {
|
|
124
|
+
process.stdout.write(response.content);
|
|
125
|
+
}
|
|
126
|
+
process.stdout.write("\n");
|
|
127
|
+
if (response.usage) {
|
|
128
|
+
console.log(chalk_1.default.gray(`\n[${response.usage.promptTokens} prompt + ${response.usage.completionTokens} completion tokens]`));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
console.error(chalk_1.default.red("\nLLM error:"), err.message);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type AuditType = "security" | "performance" | "bugs";
|
|
2
|
+
export interface AuditOptions {
|
|
3
|
+
/** Audit types to run (default: all three) */
|
|
4
|
+
types?: AuditType[];
|
|
5
|
+
/** Only audit files changed since this git ref (e.g. HEAD~5, main) */
|
|
6
|
+
since?: string;
|
|
7
|
+
/** Max context tokens per step (default: 5000) */
|
|
8
|
+
budget?: number;
|
|
9
|
+
/** Force keyword search */
|
|
10
|
+
keyword?: boolean;
|
|
11
|
+
/** Output format */
|
|
12
|
+
output?: "terminal" | "json" | "markdown";
|
|
13
|
+
/** Save critical/high findings as knowledge entries */
|
|
14
|
+
save?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function runAudit(rootDir: string, options?: AuditOptions): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB;IACpB,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;IAC1C,uDAAuD;IACvD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA0QD,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAiRf"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runAudit = runAudit;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const config_1 = require("../core/config");
|
|
11
|
+
const factory_1 = require("../llm/factory");
|
|
12
|
+
const bm25_1 = require("../search/bm25");
|
|
13
|
+
const cache_1 = require("../storage/cache");
|
|
14
|
+
const knowledge_1 = require("../storage/knowledge");
|
|
15
|
+
const repository_1 = require("../storage/repository");
|
|
16
|
+
const summaries_1 = require("../storage/summaries");
|
|
17
|
+
const tokenizer_1 = require("../utils/tokenizer");
|
|
18
|
+
const context_1 = require("./context");
|
|
19
|
+
// ─── Checklists ───────────────────────────────────────────────────────────────
|
|
20
|
+
const CHECKLISTS = {
|
|
21
|
+
security: [
|
|
22
|
+
"SQL/NoSQL injection: user input concatenated into queries without parameterization",
|
|
23
|
+
"Command injection: user input passed to exec/spawn/eval",
|
|
24
|
+
"Path traversal: user input used in file paths without normalization",
|
|
25
|
+
"XSS: unescaped user input rendered as HTML",
|
|
26
|
+
"Hardcoded secrets: API keys, passwords, tokens, private keys in source",
|
|
27
|
+
"Weak cryptography: MD5, SHA1, DES, ECB mode, hardcoded IV/salt",
|
|
28
|
+
"Missing authentication: endpoints or functions that should verify identity but don't",
|
|
29
|
+
"Missing authorization: auth checks that don't verify permissions/roles",
|
|
30
|
+
"Insecure deserialization: eval() or JSON.parse() on untrusted external input",
|
|
31
|
+
"Sensitive data in logs: passwords, tokens, PII written to logs",
|
|
32
|
+
"Open redirects: user-controlled URLs used in redirects without allowlist",
|
|
33
|
+
"CSRF: state-changing operations (POST/PUT/DELETE) without CSRF protection",
|
|
34
|
+
"Insecure direct object reference: IDs used to fetch resources without ownership check",
|
|
35
|
+
"Prototype pollution: merging user objects without sanitization",
|
|
36
|
+
],
|
|
37
|
+
performance: [
|
|
38
|
+
"N+1 queries: database or API calls inside loops",
|
|
39
|
+
"Missing await: async functions called without await, especially inside loops",
|
|
40
|
+
"Synchronous I/O: readFileSync/writeFileSync in request handlers or hot paths",
|
|
41
|
+
"Unbounded data loading: fetching all records without pagination or limits",
|
|
42
|
+
"Memory accumulation: arrays, maps, or caches that grow without eviction",
|
|
43
|
+
"Redundant computation: expensive operations (regex, sort, parse) repeated unnecessarily",
|
|
44
|
+
"Blocking event loop: CPU-intensive synchronous code in async context",
|
|
45
|
+
"Unnecessary serialization: JSON.stringify/parse in tight loops",
|
|
46
|
+
"Missing memoization: pure functions called repeatedly with same args",
|
|
47
|
+
"Large object copies: unnecessary deep clones or full object spreads",
|
|
48
|
+
"Unindexed lookups: linear search (Array.find, filter) over large collections that could use a Map",
|
|
49
|
+
"Repeated DOM/tree traversal in loops (if applicable)",
|
|
50
|
+
],
|
|
51
|
+
bugs: [
|
|
52
|
+
"Null/undefined dereference: accessing properties without null checks",
|
|
53
|
+
"Unhandled promise rejections: .then() without .catch(), missing try/catch around await",
|
|
54
|
+
"Missing error handling: no error path in critical operations (network, disk, parse)",
|
|
55
|
+
"Off-by-one: array indexing with length instead of length-1, loop bounds",
|
|
56
|
+
"Race conditions: shared mutable state accessed across concurrent async operations",
|
|
57
|
+
"Type coercion: == instead of ===, implicit conversions causing unexpected behavior",
|
|
58
|
+
"Infinite loops: while/for loops missing a guaranteed exit condition",
|
|
59
|
+
"Resource leaks: file handles, sockets, DB connections not closed in error paths",
|
|
60
|
+
"Dead code: unreachable branches, unused variables that suggest logic errors",
|
|
61
|
+
"Incorrect error propagation: errors swallowed in catch blocks (empty catch, console.log only)",
|
|
62
|
+
"Mutating function arguments: modifying caller's objects unexpectedly",
|
|
63
|
+
"Integer overflow / float precision: arithmetic on large numbers without guards",
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
// ─── Prompts ──────────────────────────────────────────────────────────────────
|
|
67
|
+
function buildAuditPlannerPrompt(types, fileCount) {
|
|
68
|
+
const checklistSections = types
|
|
69
|
+
.map((t) => `### ${t.toUpperCase()}\n${CHECKLISTS[t].map((c) => `- ${c}`).join("\n")}`)
|
|
70
|
+
.join("\n\n");
|
|
71
|
+
return (`You are an expert code auditor.\n` +
|
|
72
|
+
`Create a systematic audit plan covering ALL ${fileCount} listed files.\n\n` +
|
|
73
|
+
`Audit focus:\n${checklistSections}\n\n` +
|
|
74
|
+
`Rules:\n` +
|
|
75
|
+
`- Group 2-5 related files per step (by directory or responsibility).\n` +
|
|
76
|
+
`- Each step's description must name the specific checklist items to verify.\n` +
|
|
77
|
+
`- Cover EVERY file — no file may be skipped.\n` +
|
|
78
|
+
`- Keep steps ≤ 20 total.\n\n` +
|
|
79
|
+
`Return ONLY valid JSON — no markdown fences, no explanation:\n` +
|
|
80
|
+
`{ "steps": [{ "id": 1, "files": ["src/path.ts"], "description": "<what to check and why>" }] }`);
|
|
81
|
+
}
|
|
82
|
+
const AUDIT_EXECUTOR_PROMPT = `You are an expert code auditor.\n` +
|
|
83
|
+
`Analyze the provided code carefully for the issues described.\n\n` +
|
|
84
|
+
`Return ONLY valid JSON — no markdown, no explanation:\n` +
|
|
85
|
+
`{ "findings": [{ "severity": "critical|high|medium|low|info", "category": "<issue type>", "file": "<relative path>", "line": <number or null>, "description": "<what the issue is and why it matters>", "recommendation": "<specific fix>" }] }\n\n` +
|
|
86
|
+
`If no issues found, return: { "findings": [] }\n` +
|
|
87
|
+
`Severity guide: critical=exploitable/data loss, high=significant risk, medium=should fix, low=minor, info=note.`;
|
|
88
|
+
// ─── Git helpers ──────────────────────────────────────────────────────────────
|
|
89
|
+
function getChangedFiles(since, rootDir) {
|
|
90
|
+
const result = (0, child_process_1.spawnSync)("git", ["diff", "--name-only", since, "--", "."], { cwd: rootDir, encoding: "utf-8" });
|
|
91
|
+
if (result.status !== 0 || !result.stdout?.trim())
|
|
92
|
+
return [];
|
|
93
|
+
return result.stdout
|
|
94
|
+
.trim()
|
|
95
|
+
.split("\n")
|
|
96
|
+
.filter(Boolean);
|
|
97
|
+
}
|
|
98
|
+
// ─── Finding helpers ──────────────────────────────────────────────────────────
|
|
99
|
+
function parseFindings(raw) {
|
|
100
|
+
const text = raw.trim();
|
|
101
|
+
const jsonStr = text.startsWith("```")
|
|
102
|
+
? text.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "")
|
|
103
|
+
: text;
|
|
104
|
+
try {
|
|
105
|
+
const parsed = JSON.parse(jsonStr);
|
|
106
|
+
return Array.isArray(parsed.findings) ? parsed.findings : [];
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Fallback: try to find any JSON object in the response
|
|
110
|
+
const match = jsonStr.match(/\{[\s\S]*\}/);
|
|
111
|
+
if (match) {
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(match[0]);
|
|
114
|
+
return Array.isArray(parsed.findings) ? parsed.findings : [];
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function deduplicateFindings(findings) {
|
|
124
|
+
const seen = new Set();
|
|
125
|
+
return findings.filter((f) => {
|
|
126
|
+
const key = `${f.file}:${f.line ?? ""}:${f.category}:${f.description.slice(0, 60)}`;
|
|
127
|
+
if (seen.has(key))
|
|
128
|
+
return false;
|
|
129
|
+
seen.add(key);
|
|
130
|
+
return true;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const SEVERITY_ORDER = {
|
|
134
|
+
critical: 0,
|
|
135
|
+
high: 1,
|
|
136
|
+
medium: 2,
|
|
137
|
+
low: 3,
|
|
138
|
+
info: 4,
|
|
139
|
+
};
|
|
140
|
+
function sortFindings(findings) {
|
|
141
|
+
return [...findings].sort((a, b) => (SEVERITY_ORDER[a.severity] ?? 5) - (SEVERITY_ORDER[b.severity] ?? 5));
|
|
142
|
+
}
|
|
143
|
+
// ─── Report formatters ────────────────────────────────────────────────────────
|
|
144
|
+
const SEVERITY_STYLE = {
|
|
145
|
+
critical: (s) => chalk_1.default.bgRed.white.bold(s),
|
|
146
|
+
high: (s) => chalk_1.default.red.bold(s),
|
|
147
|
+
medium: (s) => chalk_1.default.yellow(s),
|
|
148
|
+
low: (s) => chalk_1.default.gray(s),
|
|
149
|
+
info: (s) => chalk_1.default.dim(s),
|
|
150
|
+
};
|
|
151
|
+
function formatTerminal(findings, types, auditedFiles) {
|
|
152
|
+
const counts = {
|
|
153
|
+
critical: 0,
|
|
154
|
+
high: 0,
|
|
155
|
+
medium: 0,
|
|
156
|
+
low: 0,
|
|
157
|
+
info: 0,
|
|
158
|
+
};
|
|
159
|
+
for (const f of findings)
|
|
160
|
+
counts[f.severity] = (counts[f.severity] ?? 0) + 1;
|
|
161
|
+
const typeLabel = types.join(" + ");
|
|
162
|
+
console.log(chalk_1.default.bold.cyan(`\n── Audit Report [${typeLabel}] ─────────────────────────────`));
|
|
163
|
+
console.log(chalk_1.default.gray(` ${auditedFiles} file(s) analysed · ${findings.length} finding(s)\n`));
|
|
164
|
+
if (findings.length === 0) {
|
|
165
|
+
console.log(chalk_1.default.green(" No issues found.\n"));
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
for (const f of findings) {
|
|
169
|
+
const severityBadge = SEVERITY_STYLE[f.severity](`[${f.severity.toUpperCase()}]`);
|
|
170
|
+
const location = f.line ? `${f.file}:${f.line}` : f.file;
|
|
171
|
+
console.log(`${severityBadge} ${chalk_1.default.bold(f.category)} ${chalk_1.default.gray(location)}`);
|
|
172
|
+
console.log(` ${f.description}`);
|
|
173
|
+
console.log(chalk_1.default.green(` → ${f.recommendation}`));
|
|
174
|
+
console.log();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const summary = ["critical", "high", "medium", "low", "info"]
|
|
178
|
+
.map((s) => {
|
|
179
|
+
const n = counts[s];
|
|
180
|
+
if (n === 0)
|
|
181
|
+
return null;
|
|
182
|
+
return SEVERITY_STYLE[s](`${n} ${s}`);
|
|
183
|
+
})
|
|
184
|
+
.filter(Boolean)
|
|
185
|
+
.join(chalk_1.default.gray(" · "));
|
|
186
|
+
console.log(chalk_1.default.bold.cyan("─────────────────────────────────────────────────────────"));
|
|
187
|
+
console.log(` ${summary || chalk_1.default.green("0 issues")}`);
|
|
188
|
+
console.log();
|
|
189
|
+
}
|
|
190
|
+
function formatMarkdown(findings, types, auditedFiles) {
|
|
191
|
+
const lines = [
|
|
192
|
+
`# Audit Report — ${types.join(", ")}`,
|
|
193
|
+
"",
|
|
194
|
+
`**Files analysed:** ${auditedFiles} **Findings:** ${findings.length}`,
|
|
195
|
+
"",
|
|
196
|
+
];
|
|
197
|
+
if (findings.length === 0) {
|
|
198
|
+
lines.push("No issues found.");
|
|
199
|
+
return lines.join("\n");
|
|
200
|
+
}
|
|
201
|
+
const bySeverity = {};
|
|
202
|
+
for (const f of findings) {
|
|
203
|
+
(bySeverity[f.severity] ??= []).push(f);
|
|
204
|
+
}
|
|
205
|
+
for (const sev of ["critical", "high", "medium", "low", "info"]) {
|
|
206
|
+
const group = bySeverity[sev];
|
|
207
|
+
if (!group?.length)
|
|
208
|
+
continue;
|
|
209
|
+
lines.push(`## ${sev.charAt(0).toUpperCase() + sev.slice(1)} (${group.length})`);
|
|
210
|
+
lines.push("");
|
|
211
|
+
for (const f of group) {
|
|
212
|
+
const loc = f.line ? `\`${f.file}:${f.line}\`` : `\`${f.file}\``;
|
|
213
|
+
lines.push(`### ${f.category} — ${loc}`);
|
|
214
|
+
lines.push(`**Issue:** ${f.description}`);
|
|
215
|
+
lines.push(`**Fix:** ${f.recommendation}`);
|
|
216
|
+
lines.push("");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return lines.join("\n");
|
|
220
|
+
}
|
|
221
|
+
// ─── Main command ─────────────────────────────────────────────────────────────
|
|
222
|
+
async function runAudit(rootDir, options = {}) {
|
|
223
|
+
const config = (0, config_1.loadConfig)(rootDir);
|
|
224
|
+
if (!config.summarization) {
|
|
225
|
+
console.error(chalk_1.default.red('No LLM configured. Add a "summarization" block to .vemora/config.json.'));
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
const types = options.types ?? ["security", "performance", "bugs"];
|
|
229
|
+
const budget = options.budget ?? 5000;
|
|
230
|
+
const plannerConfig = config.planner ?? config.summarization;
|
|
231
|
+
const executorConfig = config.summarization;
|
|
232
|
+
const planner = (0, factory_1.createLLMProvider)(plannerConfig);
|
|
233
|
+
const executor = (0, factory_1.createLLMProvider)(executorConfig);
|
|
234
|
+
const sameLLM = plannerConfig.provider === executorConfig.provider &&
|
|
235
|
+
plannerConfig.model === executorConfig.model;
|
|
236
|
+
console.log(chalk_1.default.bold.cyan("\n[vemora audit]"));
|
|
237
|
+
console.log(chalk_1.default.gray(` Types: ${types.join(", ")}`));
|
|
238
|
+
console.log(chalk_1.default.gray(` Planner: ${planner.name} · ${plannerConfig.model}${sameLLM ? " (also executor)" : ""}`));
|
|
239
|
+
if (!sameLLM) {
|
|
240
|
+
console.log(chalk_1.default.gray(` Executor: ${executor.name} · ${executorConfig.model}`));
|
|
241
|
+
}
|
|
242
|
+
// ── Load index data ────────────────────────────────────────────────────────
|
|
243
|
+
const repo = new repository_1.RepositoryStorage(rootDir);
|
|
244
|
+
const cacheStorage = new cache_1.EmbeddingCacheStorage(config.projectId);
|
|
245
|
+
const summaryStorage = new summaries_1.SummaryStorage(rootDir);
|
|
246
|
+
const chunks = repo.loadChunks();
|
|
247
|
+
if (chunks.length === 0) {
|
|
248
|
+
console.error(chalk_1.default.red("No index found. Run `vemora index` first."));
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
const symbols = repo.loadSymbols();
|
|
252
|
+
const depGraph = repo.loadDeps();
|
|
253
|
+
const callGraph = repo.loadCallGraph();
|
|
254
|
+
const fileSummaries = summaryStorage.hasFileSummaries()
|
|
255
|
+
? summaryStorage.loadFileSummaries()
|
|
256
|
+
: {};
|
|
257
|
+
const projectOverview = summaryStorage.loadProjectSummary()?.overview ?? null;
|
|
258
|
+
const knowledgeEntries = new knowledge_1.KnowledgeStorage(rootDir).load();
|
|
259
|
+
// ── Determine file scope ───────────────────────────────────────────────────
|
|
260
|
+
let targetFiles = Object.keys(Object.keys(fileSummaries).length > 0
|
|
261
|
+
? fileSummaries
|
|
262
|
+
: repo.loadFiles());
|
|
263
|
+
if (options.since) {
|
|
264
|
+
const changed = getChangedFiles(options.since, rootDir);
|
|
265
|
+
if (changed.length === 0) {
|
|
266
|
+
console.log(chalk_1.default.yellow(` No changed files since ${options.since}.`));
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
// Keep only indexed files that appear in the diff
|
|
270
|
+
const changedSet = new Set(changed);
|
|
271
|
+
targetFiles = targetFiles.filter((f) => changedSet.has(f));
|
|
272
|
+
if (targetFiles.length === 0) {
|
|
273
|
+
console.log(chalk_1.default.yellow(" No indexed files in the diff — nothing to audit."));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
console.log(chalk_1.default.gray(` Scope: ${changed.length} changed file(s) since ${options.since}`));
|
|
277
|
+
}
|
|
278
|
+
console.log(chalk_1.default.gray(` Files: ${targetFiles.length}`));
|
|
279
|
+
console.log();
|
|
280
|
+
// ── Build planner context (summaries + file list, no raw code) ─────────────
|
|
281
|
+
const fileListSection = targetFiles
|
|
282
|
+
.map((f) => {
|
|
283
|
+
const summary = fileSummaries[f]?.summary;
|
|
284
|
+
return summary ? `${f} — ${summary}` : f;
|
|
285
|
+
})
|
|
286
|
+
.join("\n");
|
|
287
|
+
const plannerContext = `# Project: ${config.projectName}\n\n` +
|
|
288
|
+
(projectOverview ? `## Overview\n${projectOverview}\n\n` : "") +
|
|
289
|
+
`## Files to audit (${targetFiles.length})\n${fileListSection}`;
|
|
290
|
+
// ── Phase 1: generate audit plan ───────────────────────────────────────────
|
|
291
|
+
const planSpinner = (0, ora_1.default)("Generating audit plan...").start();
|
|
292
|
+
let steps = [];
|
|
293
|
+
try {
|
|
294
|
+
const plannerResponse = await planner.chat([
|
|
295
|
+
{
|
|
296
|
+
role: "system",
|
|
297
|
+
content: buildAuditPlannerPrompt(types, targetFiles.length),
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
role: "user",
|
|
301
|
+
content: `Generate the audit plan for this project:\n\n${plannerContext}`,
|
|
302
|
+
},
|
|
303
|
+
], { model: plannerConfig.model, temperature: 0.1 });
|
|
304
|
+
const raw = plannerResponse.content.trim();
|
|
305
|
+
const jsonStr = raw.startsWith("```")
|
|
306
|
+
? raw.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "")
|
|
307
|
+
: raw;
|
|
308
|
+
const plan = JSON.parse(jsonStr);
|
|
309
|
+
steps = plan.steps ?? [];
|
|
310
|
+
if (steps.length === 0)
|
|
311
|
+
throw new Error("Plan has no steps");
|
|
312
|
+
planSpinner.succeed(`Audit plan ready — ${steps.length} step${steps.length !== 1 ? "s" : ""}`);
|
|
313
|
+
}
|
|
314
|
+
catch (err) {
|
|
315
|
+
planSpinner.fail(`Planning failed: ${err.message}`);
|
|
316
|
+
process.exit(1);
|
|
317
|
+
}
|
|
318
|
+
// ── Phase 2: execute steps in parallel waves of 3 ─────────────────────────
|
|
319
|
+
const allFindings = [];
|
|
320
|
+
const contextCache = new Map();
|
|
321
|
+
const WAVE_SIZE = 3;
|
|
322
|
+
for (let i = 0; i < steps.length; i += WAVE_SIZE) {
|
|
323
|
+
const wave = steps.slice(i, i + WAVE_SIZE);
|
|
324
|
+
const waveLabel = `[${i + 1}-${Math.min(i + WAVE_SIZE, steps.length)}/${steps.length}]`;
|
|
325
|
+
const waveSpinner = (0, ora_1.default)(`${waveLabel} ${wave.map((s) => s.description.slice(0, 40)).join(" | ")}...`).start();
|
|
326
|
+
const waveResults = await Promise.all(wave.map(async (step) => {
|
|
327
|
+
// Context retrieval with deduplication
|
|
328
|
+
const cacheKey = JSON.stringify([...step.files].sort());
|
|
329
|
+
let contextStr = contextCache.get(cacheKey);
|
|
330
|
+
if (!contextStr) {
|
|
331
|
+
// Targeted retrieval: pull chunks for these exact files
|
|
332
|
+
const fileSet = new Set(step.files);
|
|
333
|
+
let results = chunks
|
|
334
|
+
.filter((c) => fileSet.has(c.file))
|
|
335
|
+
.map((chunk) => ({
|
|
336
|
+
chunk,
|
|
337
|
+
score: 1,
|
|
338
|
+
symbol: chunk.symbol ? symbols[chunk.symbol] : undefined,
|
|
339
|
+
}));
|
|
340
|
+
// Fallback to keyword search if targeted retrieval is empty
|
|
341
|
+
if (results.length === 0) {
|
|
342
|
+
results = (0, bm25_1.computeBM25Scores)(step.description, chunks, symbols, 10);
|
|
343
|
+
}
|
|
344
|
+
results = (0, tokenizer_1.applyTokenBudget)(results, budget);
|
|
345
|
+
contextStr = (0, context_1.generateContextString)(config, results, depGraph, callGraph, fileSummaries, projectOverview, { query: step.description, format: "plain" }, rootDir, chunks, knowledgeEntries);
|
|
346
|
+
contextCache.set(cacheKey, contextStr);
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const response = await executor.chat([
|
|
350
|
+
{
|
|
351
|
+
role: "system",
|
|
352
|
+
content: `${AUDIT_EXECUTOR_PROMPT}\n\n${contextStr}`,
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
role: "user",
|
|
356
|
+
content: `Audit these files: ${step.files.join(", ")}\n\n` +
|
|
357
|
+
`Focus on: ${step.description}`,
|
|
358
|
+
},
|
|
359
|
+
], { model: executorConfig.model, temperature: 0.1 });
|
|
360
|
+
return parseFindings(response.content);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return [];
|
|
364
|
+
}
|
|
365
|
+
}));
|
|
366
|
+
for (const findings of waveResults) {
|
|
367
|
+
allFindings.push(...findings);
|
|
368
|
+
}
|
|
369
|
+
const waveCount = waveResults.flat().length;
|
|
370
|
+
waveSpinner.succeed(`${waveLabel} done — ${waveCount} finding${waveCount !== 1 ? "s" : ""}`);
|
|
371
|
+
}
|
|
372
|
+
// ── Phase 3: aggregate, deduplicate, sort ─────────────────────────────────
|
|
373
|
+
const finalFindings = sortFindings(deduplicateFindings(allFindings));
|
|
374
|
+
// ── Phase 4: output ────────────────────────────────────────────────────────
|
|
375
|
+
const outputFormat = options.output ?? "terminal";
|
|
376
|
+
if (outputFormat === "json") {
|
|
377
|
+
console.log(JSON.stringify({ findings: finalFindings }, null, 2));
|
|
378
|
+
}
|
|
379
|
+
else if (outputFormat === "markdown") {
|
|
380
|
+
console.log(formatMarkdown(finalFindings, types, targetFiles.length));
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
formatTerminal(finalFindings, types, targetFiles.length);
|
|
384
|
+
}
|
|
385
|
+
// ── Phase 5: optionally save critical/high findings as knowledge ───────────
|
|
386
|
+
if (options.save) {
|
|
387
|
+
const important = finalFindings.filter((f) => f.severity === "critical" || f.severity === "high");
|
|
388
|
+
if (important.length > 0) {
|
|
389
|
+
const knowledge = new knowledge_1.KnowledgeStorage(rootDir);
|
|
390
|
+
const entries = knowledge.load();
|
|
391
|
+
for (const f of important) {
|
|
392
|
+
entries.push({
|
|
393
|
+
id: Math.random().toString(36).slice(2),
|
|
394
|
+
category: "gotcha",
|
|
395
|
+
title: `[${f.severity.toUpperCase()}] ${f.category} — ${f.file}`,
|
|
396
|
+
body: `${f.description}\n\nRecommendation: ${f.recommendation}`,
|
|
397
|
+
relatedFiles: [f.file],
|
|
398
|
+
createdAt: new Date().toISOString(),
|
|
399
|
+
createdBy: `llm:${executorConfig.model}`,
|
|
400
|
+
confidence: f.severity === "critical" ? "high" : "medium",
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
knowledge.save(entries);
|
|
404
|
+
console.log(chalk_1.default.green(` ${important.length} critical/high finding(s) saved to knowledge store.`));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface BriefOptions {
|
|
2
|
+
/** Include all knowledge entries, not only high-confidence ones. */
|
|
3
|
+
all?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Prints a compact session primer (~L0 + L1 in mempalace terms):
|
|
7
|
+
* - Project overview (from vemora summarize)
|
|
8
|
+
* - High-confidence knowledge entries
|
|
9
|
+
*
|
|
10
|
+
* Designed to be run at the start of an LLM session to re-establish context
|
|
11
|
+
* without loading the full index. Optimised for minimal token use.
|
|
12
|
+
*/
|
|
13
|
+
export declare function runBrief(rootDir: string, options?: BriefOptions): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../src/commands/brief.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAmEf"}
|