nexus-agents 3.5.0 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-NWTACWXE.js → chunk-66QB5SML.js} +2 -2
- package/dist/{chunk-YF35FKKD.js → chunk-BQTMMLQQ.js} +15 -7
- package/dist/chunk-BQTMMLQQ.js.map +1 -0
- package/dist/{chunk-3EIACKNR.js → chunk-J2FUCIPH.js} +3 -3
- package/dist/{chunk-DDY7JDTZ.js → chunk-W7532ZQG.js} +127 -33
- package/dist/chunk-W7532ZQG.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/{codebase-search-LUF5YJLQ.js → codebase-search-AATGEN2H.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{setup-command-ISVGN73J.js → setup-command-DOPNW32N.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-DDY7JDTZ.js.map +0 -1
- package/dist/chunk-YF35FKKD.js.map +0 -1
- /package/dist/{chunk-NWTACWXE.js.map → chunk-66QB5SML.js.map} +0 -0
- /package/dist/{chunk-3EIACKNR.js.map → chunk-J2FUCIPH.js.map} +0 -0
- /package/dist/{codebase-search-LUF5YJLQ.js.map → codebase-search-AATGEN2H.js.map} +0 -0
- /package/dist/{setup-command-ISVGN73J.js.map → setup-command-DOPNW32N.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
checkSqlite,
|
|
9
9
|
defaultConfig,
|
|
10
10
|
initDataDirectories
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-J2FUCIPH.js";
|
|
12
12
|
import {
|
|
13
13
|
BUILT_IN_EXPERTS
|
|
14
14
|
} from "./chunk-YPNQPT2F.js";
|
|
@@ -2001,4 +2001,4 @@ export {
|
|
|
2001
2001
|
setupCommand,
|
|
2002
2002
|
setupCommandAsync
|
|
2003
2003
|
};
|
|
2004
|
-
//# sourceMappingURL=chunk-
|
|
2004
|
+
//# sourceMappingURL=chunk-66QB5SML.js.map
|
|
@@ -6,6 +6,7 @@ import { resolve, extname as extname2, relative } from "path";
|
|
|
6
6
|
import { readFile } from "fs/promises";
|
|
7
7
|
import { extname } from "path";
|
|
8
8
|
import ts from "typescript";
|
|
9
|
+
var SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
|
|
9
10
|
function getKind(node) {
|
|
10
11
|
if (ts.isFunctionDeclaration(node)) return "function";
|
|
11
12
|
if (ts.isClassDeclaration(node)) return "class";
|
|
@@ -86,14 +87,15 @@ function computeSavings(totalChars, symbolChars) {
|
|
|
86
87
|
}
|
|
87
88
|
async function extractSymbols(filePath) {
|
|
88
89
|
const ext = extname(filePath).toLowerCase();
|
|
89
|
-
if (!
|
|
90
|
+
if (!SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
90
91
|
return {
|
|
91
92
|
filePath,
|
|
92
93
|
symbols: [],
|
|
93
94
|
totalLines: 0,
|
|
94
95
|
totalChars: 0,
|
|
95
96
|
symbolChars: 0,
|
|
96
|
-
savingsPercent: 0
|
|
97
|
+
savingsPercent: 0,
|
|
98
|
+
parsed: false
|
|
97
99
|
};
|
|
98
100
|
}
|
|
99
101
|
const source = await readFile(filePath, "utf-8");
|
|
@@ -110,12 +112,17 @@ async function extractSymbols(filePath) {
|
|
|
110
112
|
totalLines: source.split("\n").length,
|
|
111
113
|
totalChars,
|
|
112
114
|
symbolChars,
|
|
113
|
-
savingsPercent: computeSavings(totalChars, symbolChars)
|
|
115
|
+
savingsPercent: computeSavings(totalChars, symbolChars),
|
|
116
|
+
parsed: true
|
|
114
117
|
};
|
|
115
118
|
}
|
|
116
|
-
async function
|
|
119
|
+
async function extractSymbolIndexResult(filePath) {
|
|
117
120
|
const result = await extractSymbols(filePath);
|
|
118
|
-
if (result.
|
|
121
|
+
if (!result.parsed) return { kind: "empty", reason: "unsupported" };
|
|
122
|
+
if (result.symbols.length === 0) return { kind: "empty", reason: "no-declarations" };
|
|
123
|
+
return { kind: "index", index: renderIndex(filePath, result) };
|
|
124
|
+
}
|
|
125
|
+
function renderIndex(filePath, result) {
|
|
119
126
|
const lines = result.symbols.map((s) => {
|
|
120
127
|
const exp = s.exported ? "export " : "";
|
|
121
128
|
return `${exp}${s.kind} ${s.name} (L${String(s.startLine)}-${String(s.endLine)})`;
|
|
@@ -257,11 +264,12 @@ var CodebaseIndex = class {
|
|
|
257
264
|
};
|
|
258
265
|
|
|
259
266
|
export {
|
|
267
|
+
SUPPORTED_EXTENSIONS,
|
|
260
268
|
extractSymbols,
|
|
261
|
-
|
|
269
|
+
extractSymbolIndexResult,
|
|
262
270
|
DEFAULT_INDEX_MAX_DEPTH,
|
|
263
271
|
MAX_INDEX_MAX_DEPTH,
|
|
264
272
|
findSourceFiles,
|
|
265
273
|
CodebaseIndex
|
|
266
274
|
};
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
275
|
+
//# sourceMappingURL=chunk-BQTMMLQQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer/codebase-search.ts","../src/indexer/symbol-extractor.ts"],"sourcesContent":["/**\n * Codebase search — keyword search across symbol indices.\n *\n * Builds an in-memory symbol index for a directory of TS/JS files,\n * then supports keyword search, file summaries, and symbol lookup.\n *\n * Inspired by Augment Code's Context Engine. Uses the existing\n * extractSymbols() function for AST parsing.\n *\n * @module indexer/codebase-search\n */\n\nimport { readdir } from 'node:fs/promises';\nimport { resolve, extname, relative } from 'node:path';\nimport {\n extractSymbols,\n type CodeSymbol,\n type SymbolExtractionResult,\n} from './symbol-extractor.js';\n\n/** A symbol with its source file path. */\nexport interface IndexedSymbol extends CodeSymbol {\n /** Relative file path from the indexed root. */\n filePath: string;\n}\n\n/** Search result with relevance scoring. */\nexport interface SearchResult {\n symbol: IndexedSymbol;\n /** Relevance score (higher = better match). */\n score: number;\n /** How the query matched (exact, prefix, substring, word). */\n matchType: 'exact' | 'prefix' | 'substring' | 'word';\n}\n\n/** File summary — compact overview of a source file. */\nexport interface FileSummary {\n filePath: string;\n totalLines: number;\n exportedSymbols: number;\n privateSymbols: number;\n kinds: Record<string, number>;\n}\n\n/** Index statistics. */\nexport interface IndexStats {\n totalFiles: number;\n totalSymbols: number;\n indexedAt: string;\n /** Directories not descended into because `maxDepth` was exhausted (#4243). */\n skippedDirs: number;\n}\n\n/** Default recursion depth for `CodebaseIndex.index()` (#4243 — was hardcoded 4). */\nexport const DEFAULT_INDEX_MAX_DEPTH = 24;\n/** Upper clamp for caller-supplied `maxDepth` to bound worst-case tree-walk cost. */\nexport const MAX_INDEX_MAX_DEPTH = 64;\n\n// Score weights for different match types\nconst SCORE_EXACT = 20;\nconst SCORE_PREFIX = 10;\nconst SCORE_WORD = 5;\nconst SCORE_SUBSTRING = 2;\nconst SCORE_EXPORTED_BONUS = 3;\n\nfunction isSourceFile(name: string): boolean {\n const ext = extname(name).toLowerCase();\n return (\n ['.ts', '.tsx', '.js', '.jsx'].includes(ext) &&\n !name.endsWith('.test.ts') &&\n !name.endsWith('.test.tsx') &&\n !name.endsWith('.d.ts')\n );\n}\n\n/** Result of a recursive source-file walk: the files found plus a truncation signal. */\nexport interface FindSourceFilesResult {\n files: string[];\n /** Count of directories that were NOT descended into because maxDepth hit 0. */\n skippedDirs: number;\n}\n\n/**\n * Recursively collect TS/JS source files under `dir`, bounded by `maxDepth`,\n * skipping `node_modules`/`dist` and test/declaration files. Exported so the\n * `search_usages` tool (#4265) reuses the exact same source-file set the symbol\n * index walks — keeping the two tools' scopes apples-to-apples (DRY).\n */\nexport async function findSourceFiles(\n dir: string,\n maxDepth: number\n): Promise<FindSourceFilesResult> {\n if (maxDepth <= 0) return { files: [], skippedDirs: 1 };\n const files: string[] = [];\n let skippedDirs = 0;\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n for (const entry of entries) {\n const fullPath = resolve(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== 'dist') {\n const sub = await findSourceFiles(fullPath, maxDepth - 1);\n files.push(...sub.files);\n skippedDirs += sub.skippedDirs;\n }\n if (entry.isFile() && isSourceFile(entry.name)) {\n files.push(fullPath);\n }\n }\n return { files, skippedDirs };\n}\n\nfunction scoreMatch(symbolName: string, query: string): SearchResult['score'] | null {\n const nameLower = symbolName.toLowerCase();\n const queryLower = query.toLowerCase();\n\n if (nameLower === queryLower) return SCORE_EXACT;\n if (nameLower.startsWith(queryLower)) return SCORE_PREFIX;\n\n // Word boundary match (camelCase splitting)\n const words = symbolName\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .split(/[\\s_-]+/);\n if (words.some((w) => w === queryLower)) return SCORE_WORD;\n\n if (nameLower.includes(queryLower)) return SCORE_SUBSTRING;\n\n return null;\n}\n\nfunction getMatchType(score: number): SearchResult['matchType'] {\n if (score >= SCORE_EXACT) return 'exact';\n if (score >= SCORE_PREFIX) return 'prefix';\n if (score >= SCORE_WORD) return 'word';\n return 'substring';\n}\n\n/** In-memory codebase symbol index. */\nexport class CodebaseIndex {\n private readonly symbols: IndexedSymbol[] = [];\n private readonly fileResults = new Map<string, SymbolExtractionResult>();\n private readonly rootDir: string;\n private skippedDirs = 0;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n /**\n * Index all TS/JS source files in the directory.\n *\n * `maxDepth` is clamped to `[1, MAX_INDEX_MAX_DEPTH]` so a caller-supplied\n * value can't force an unbounded tree-walk (#4243).\n */\n async index(maxDepth: number = DEFAULT_INDEX_MAX_DEPTH): Promise<IndexStats> {\n const clampedDepth = Math.min(Math.max(maxDepth, 1), MAX_INDEX_MAX_DEPTH);\n const { files, skippedDirs } = await findSourceFiles(this.rootDir, clampedDepth);\n this.skippedDirs = skippedDirs;\n\n for (const file of files) {\n const result = await extractSymbols(file);\n const relPath = relative(this.rootDir, file);\n this.fileResults.set(relPath, result);\n\n for (const symbol of result.symbols) {\n this.symbols.push({ ...symbol, filePath: relPath });\n }\n }\n\n return {\n totalFiles: files.length,\n totalSymbols: this.symbols.length,\n indexedAt: new Date().toISOString(),\n skippedDirs,\n };\n }\n\n /** Search symbols by keyword. Returns top N results sorted by relevance. */\n search(query: string, limit = 20): SearchResult[] {\n const results: SearchResult[] = [];\n\n for (const symbol of this.symbols) {\n const baseScore = scoreMatch(symbol.name, query);\n if (baseScore === null) continue;\n\n const bonus = symbol.exported ? SCORE_EXPORTED_BONUS : 0;\n results.push({\n symbol,\n score: baseScore + bonus,\n matchType: getMatchType(baseScore),\n });\n }\n\n return results.sort((a, b) => b.score - a.score).slice(0, limit);\n }\n\n /** Get a compact summary of a file's symbols. */\n getFileSummary(filePath: string): FileSummary | undefined {\n const result = this.fileResults.get(filePath);\n if (result === undefined) return undefined;\n\n const kinds: Record<string, number> = {};\n let exported = 0;\n let priv = 0;\n\n for (const s of result.symbols) {\n kinds[s.kind] = (kinds[s.kind] ?? 0) + 1;\n if (s.exported) exported++;\n else priv++;\n }\n\n return {\n filePath,\n totalLines: result.totalLines,\n exportedSymbols: exported,\n privateSymbols: priv,\n kinds,\n };\n }\n\n /** List all indexed files with symbol counts. */\n listFiles(): Array<{ path: string; symbols: number; lines: number }> {\n return [...this.fileResults.entries()].map(([path, result]) => ({\n path,\n symbols: result.symbols.length,\n lines: result.totalLines,\n }));\n }\n\n /** Get index statistics. */\n get stats(): { files: number; symbols: number; skippedDirs: number } {\n return {\n files: this.fileResults.size,\n symbols: this.symbols.length,\n skippedDirs: this.skippedDirs,\n };\n }\n}\n","/**\n * AST symbol extraction for token-efficient code retrieval.\n *\n * Uses TypeScript's compiler API to extract function, class, method,\n * interface, and type definitions from source files.\n *\n * Token savings: ~80-99% vs reading full files.\n * No additional dependencies — uses TypeScript (already a project dep).\n *\n * @module indexer/symbol-extractor\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport ts from 'typescript';\n\n/** A symbol extracted from source code. */\nexport interface CodeSymbol {\n /** Symbol name */\n name: string;\n /** Symbol kind */\n kind: 'function' | 'class' | 'method' | 'interface' | 'type' | 'variable' | 'enum';\n /** Start line (1-based) */\n startLine: number;\n /** End line (1-based) */\n endLine: number;\n /** Full source text of the symbol */\n text: string;\n /** Whether the symbol is exported */\n exported: boolean;\n}\n\n/**\n * Extensions the TypeScript compiler API path can parse (#4517).\n *\n * Exported so the tool layer can name them in its error message instead of\n * asserting a file \"may not be TypeScript/JavaScript\" without saying what\n * would count.\n */\nexport const SUPPORTED_EXTENSIONS: readonly string[] = ['.ts', '.tsx', '.js', '.jsx'];\n\n/** Result of extracting symbols from a file. */\nexport interface SymbolExtractionResult {\n filePath: string;\n symbols: CodeSymbol[];\n totalLines: number;\n totalChars: number;\n symbolChars: number;\n savingsPercent: number;\n /**\n * Whether the file was actually parsed (#4517).\n *\n * `false` means the extension is not supported, so `symbols: []` reports\n * that nothing was READ — not that nothing is there. An unsupported file and\n * a genuinely symbol-free file previously returned identical results, and\n * the tool guessed between them wrongly: a valid TypeScript barrel of 20\n * re-exports was reported as possibly-not-TypeScript.\n */\n parsed: boolean;\n}\n\nfunction getKind(node: ts.Node): CodeSymbol['kind'] | null {\n if (ts.isFunctionDeclaration(node)) return 'function';\n if (ts.isClassDeclaration(node)) return 'class';\n if (ts.isInterfaceDeclaration(node)) return 'interface';\n if (ts.isTypeAliasDeclaration(node)) return 'type';\n if (ts.isEnumDeclaration(node)) return 'enum';\n if (ts.isMethodDeclaration(node)) return 'method';\n if (ts.isVariableStatement(node)) return 'variable';\n return null;\n}\n\nfunction getName(node: ts.Node): string {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isClassDeclaration(node) ||\n ts.isInterfaceDeclaration(node) ||\n ts.isTypeAliasDeclaration(node) ||\n ts.isEnumDeclaration(node) ||\n ts.isMethodDeclaration(node)\n ) {\n const nameNode = (node as ts.NamedDeclaration).name;\n return nameNode ? nameNode.getText() : '<anonymous>';\n }\n if (ts.isVariableStatement(node)) {\n const decls = node.declarationList.declarations;\n const firstDecl = decls[0];\n if (firstDecl !== undefined) {\n return firstDecl.name.getText();\n }\n }\n return '<anonymous>';\n}\n\nfunction isExported(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n if (modifiers) {\n return modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n }\n return false;\n}\n\nfunction visitNode(node: ts.Node, sourceFile: ts.SourceFile, symbols: CodeSymbol[]): void {\n const kind = getKind(node);\n if (kind !== null) {\n const name = getName(node);\n if (name !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n symbols.push({\n name,\n kind,\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: node.getText(sourceFile),\n exported: isExported(node),\n });\n }\n }\n if (ts.isClassDeclaration(node)) {\n visitClassMembers(node, sourceFile, symbols);\n return;\n }\n ts.forEachChild(node, (child) => {\n visitNode(child, sourceFile, symbols);\n });\n}\n\nfunction visitClassMembers(\n node: ts.ClassDeclaration,\n sourceFile: ts.SourceFile,\n symbols: CodeSymbol[]\n): void {\n for (const member of node.members) {\n if (ts.isMethodDeclaration(member) || ts.isPropertyDeclaration(member)) {\n const memberName = member.name.getText();\n if (memberName !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(member.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(member.getEnd());\n symbols.push({\n name: memberName,\n kind: 'method',\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: member.getText(sourceFile),\n exported: false,\n });\n }\n }\n }\n}\n\nfunction computeSavings(totalChars: number, symbolChars: number): number {\n return totalChars > 0 ? Math.round(100 * (1 - symbolChars / totalChars) * 10) / 10 : 0;\n}\n\n/**\n * Extract symbols from a TypeScript/JavaScript file.\n */\nexport async function extractSymbols(filePath: string): Promise<SymbolExtractionResult> {\n const ext = extname(filePath).toLowerCase();\n if (!SUPPORTED_EXTENSIONS.includes(ext)) {\n return {\n filePath,\n symbols: [],\n totalLines: 0,\n totalChars: 0,\n symbolChars: 0,\n savingsPercent: 0,\n parsed: false,\n };\n }\n\n const source = await readFile(filePath, 'utf-8');\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n const symbols: CodeSymbol[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n visitNode(node, sourceFile, symbols);\n });\n\n const totalChars = source.length;\n const symbolChars = symbols.reduce((sum, s) => sum + s.text.length, 0);\n\n return {\n filePath,\n symbols,\n totalLines: source.split('\\n').length,\n totalChars,\n symbolChars,\n savingsPercent: computeSavings(totalChars, symbolChars),\n parsed: true,\n };\n}\n\n/**\n * Why {@link extractSymbolIndex} produced no index (#4517).\n *\n * `unsupported` and `no-declarations` are different facts about the world:\n * the first says the file was never read, the second says it was read and\n * genuinely declares nothing locally — a re-export barrel, typically. Callers\n * that collapse them tell the user to check a file type that was never the\n * problem.\n */\nexport type EmptyIndexReason = 'unsupported' | 'no-declarations';\n\n/** A symbol index, or the reason there is none. */\nexport type SymbolIndexResult =\n | { readonly kind: 'index'; readonly index: string }\n | { readonly kind: 'empty'; readonly reason: EmptyIndexReason };\n\n/**\n * Extract a compact symbol index, reporting why when there is nothing to show.\n *\n * Names + locations only, no source text — the minimal representation for LLM\n * context (~95%+ token savings). Replaced the earlier `extractSymbolIndex`,\n * which returned a bare `''` for both \"could not read\" and \"read, found\n * nothing\" and so could not tell a caller which had happened.\n */\nexport async function extractSymbolIndexResult(filePath: string): Promise<SymbolIndexResult> {\n const result = await extractSymbols(filePath);\n if (!result.parsed) return { kind: 'empty', reason: 'unsupported' };\n if (result.symbols.length === 0) return { kind: 'empty', reason: 'no-declarations' };\n return { kind: 'index', index: renderIndex(filePath, result) };\n}\n\nfunction renderIndex(filePath: string, result: SymbolExtractionResult): string {\n const lines = result.symbols.map((s) => {\n const exp = s.exported ? 'export ' : '';\n return `${exp}${s.kind} ${s.name} (L${String(s.startLine)}-${String(s.endLine)})`;\n });\n return `// ${filePath} — ${String(result.symbols.length)} symbols\\n${lines.join('\\n')}`;\n}\n"],"mappings":"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","names":["extname","extname"]}
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
} from "./chunk-OQLFRJCW.js";
|
|
50
50
|
|
|
51
51
|
// src/version.ts
|
|
52
|
-
var VERSION = true ? "3.5.
|
|
52
|
+
var VERSION = true ? "3.5.2" : "dev";
|
|
53
53
|
|
|
54
54
|
// src/config/schemas-core.ts
|
|
55
55
|
import { z } from "zod";
|
|
@@ -2287,7 +2287,7 @@ async function runDoctorFix(result) {
|
|
|
2287
2287
|
writeLine2("\u2500".repeat(40));
|
|
2288
2288
|
let fixCount = 0;
|
|
2289
2289
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
2290
|
-
const { runSetup } = await import("./setup-command-
|
|
2290
|
+
const { runSetup } = await import("./setup-command-DOPNW32N.js");
|
|
2291
2291
|
const setupResult = runSetup({
|
|
2292
2292
|
skipMcp: true,
|
|
2293
2293
|
skipRules: true,
|
|
@@ -2400,4 +2400,4 @@ export {
|
|
|
2400
2400
|
startStdioServer,
|
|
2401
2401
|
closeServer
|
|
2402
2402
|
};
|
|
2403
|
-
//# sourceMappingURL=chunk-
|
|
2403
|
+
//# sourceMappingURL=chunk-J2FUCIPH.js.map
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
CodebaseIndex,
|
|
9
9
|
DEFAULT_INDEX_MAX_DEPTH,
|
|
10
10
|
MAX_INDEX_MAX_DEPTH,
|
|
11
|
-
|
|
11
|
+
SUPPORTED_EXTENSIONS,
|
|
12
|
+
extractSymbolIndexResult,
|
|
12
13
|
extractSymbols,
|
|
13
14
|
findSourceFiles
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BQTMMLQQ.js";
|
|
15
16
|
import {
|
|
16
17
|
FINDING_SEVERITY_LEVELS,
|
|
17
18
|
SARIF_LEVEL_MAP,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
DEFAULT_TASK_TTL_MS,
|
|
22
23
|
DEFAULT_TOOL_RATE_LIMITS,
|
|
23
24
|
clampTaskTtl
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-J2FUCIPH.js";
|
|
25
26
|
import {
|
|
26
27
|
executeExpert
|
|
27
28
|
} from "./chunk-GVLDWGSK.js";
|
|
@@ -20780,7 +20781,7 @@ import * as fs2 from "fs/promises";
|
|
|
20780
20781
|
import * as path2 from "path";
|
|
20781
20782
|
import * as yaml from "yaml";
|
|
20782
20783
|
var MAX_FILE_SIZE_BYTES = 1024 * 1024;
|
|
20783
|
-
var
|
|
20784
|
+
var SUPPORTED_EXTENSIONS2 = [".yaml", ".yml", ".json"];
|
|
20784
20785
|
function validatePath(userPath, allowedRoot) {
|
|
20785
20786
|
const resolved = resolveInsideRoot(userPath, allowedRoot);
|
|
20786
20787
|
if (resolved === null) {
|
|
@@ -20912,10 +20913,10 @@ async function loadWorkflowFile(filePath, allowedRoot = process.cwd()) {
|
|
|
20912
20913
|
}
|
|
20913
20914
|
const validatedPath = pathValidation.value;
|
|
20914
20915
|
const ext = path2.extname(validatedPath).toLowerCase();
|
|
20915
|
-
if (!
|
|
20916
|
+
if (!SUPPORTED_EXTENSIONS2.includes(ext)) {
|
|
20916
20917
|
return err(
|
|
20917
20918
|
new ParseError(
|
|
20918
|
-
`Unsupported file extension: ${ext}. Supported: ${
|
|
20919
|
+
`Unsupported file extension: ${ext}. Supported: ${SUPPORTED_EXTENSIONS2.join(", ")}`
|
|
20919
20920
|
)
|
|
20920
20921
|
);
|
|
20921
20922
|
}
|
|
@@ -41741,7 +41742,7 @@ function registerSearchCodebaseTool(server, deps) {
|
|
|
41741
41742
|
}
|
|
41742
41743
|
|
|
41743
41744
|
// src/mcp/tools/extract-symbols-tool.ts
|
|
41744
|
-
import { resolve as resolve8, sep as sep4 } from "path";
|
|
41745
|
+
import { extname as extname3, resolve as resolve8, sep as sep4 } from "path";
|
|
41745
41746
|
import { z as z81 } from "zod";
|
|
41746
41747
|
var DEFAULT_EXTRACT_MAX_CHARS = 2e4;
|
|
41747
41748
|
var DEFAULT_EXTRACT_MAX_SYMBOLS = 200;
|
|
@@ -41857,11 +41858,11 @@ async function extractSymbolsHandler(args, ctx) {
|
|
|
41857
41858
|
);
|
|
41858
41859
|
return toolSuccess(output2);
|
|
41859
41860
|
}
|
|
41860
|
-
const
|
|
41861
|
-
if (
|
|
41862
|
-
return toolSuccess(
|
|
41861
|
+
const result = await extractSymbolIndexResult(resolvedPath);
|
|
41862
|
+
if (result.kind === "empty") {
|
|
41863
|
+
return toolSuccess(emptyIndexMessage(result.reason, resolvedPath));
|
|
41863
41864
|
}
|
|
41864
|
-
return toolSuccess(index);
|
|
41865
|
+
return toolSuccess(result.index);
|
|
41865
41866
|
} catch (caught) {
|
|
41866
41867
|
const e = caught instanceof Error ? caught : new Error(String(caught));
|
|
41867
41868
|
ctx.logger.error("Symbol extraction failed", e);
|
|
@@ -41871,6 +41872,14 @@ async function extractSymbolsHandler(args, ctx) {
|
|
|
41871
41872
|
});
|
|
41872
41873
|
}
|
|
41873
41874
|
}
|
|
41875
|
+
function emptyIndexMessage(reason, filePath) {
|
|
41876
|
+
if (reason === "unsupported") {
|
|
41877
|
+
const ext = extname3(filePath).toLowerCase();
|
|
41878
|
+
const shown = ext === "" ? "(no extension)" : ext;
|
|
41879
|
+
return `Not parsed: extract_symbols cannot read ${shown} files. Supported: ${SUPPORTED_EXTENSIONS.join(", ")}. This says nothing about whether the file contains symbols.`;
|
|
41880
|
+
}
|
|
41881
|
+
return "Parsed successfully; no local declarations found. A re-export barrel (`export { X } from ...`) reports zero symbols because re-exports declare nothing locally.";
|
|
41882
|
+
}
|
|
41874
41883
|
function registerExtractSymbolsTool(server, deps) {
|
|
41875
41884
|
const logger58 = deps.logger ?? createLogger({ tool: "extract_symbols" });
|
|
41876
41885
|
const toolSchema = {
|
|
@@ -45335,6 +45344,68 @@ function buildScanSummary(total, confirmed, falsePositives, osvCount) {
|
|
|
45335
45344
|
return parts.join(", ");
|
|
45336
45345
|
}
|
|
45337
45346
|
|
|
45347
|
+
// src/security/quality-gate-commands.ts
|
|
45348
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
45349
|
+
import { join as join9 } from "path";
|
|
45350
|
+
var LOCKFILES = [
|
|
45351
|
+
{ file: "pnpm-lock.yaml", manager: "pnpm" },
|
|
45352
|
+
{ file: "yarn.lock", manager: "yarn" },
|
|
45353
|
+
{ file: "bun.lockb", manager: "bun" },
|
|
45354
|
+
{ file: "package-lock.json", manager: "npm" }
|
|
45355
|
+
];
|
|
45356
|
+
var SCRIPT_CANDIDATES = {
|
|
45357
|
+
lint: ["lint"],
|
|
45358
|
+
typecheck: ["typecheck", "type-check", "types"],
|
|
45359
|
+
tests: ["test", "tests"],
|
|
45360
|
+
build: ["build"]
|
|
45361
|
+
};
|
|
45362
|
+
function detectPackageManager(projectDir) {
|
|
45363
|
+
for (const { file, manager } of LOCKFILES) {
|
|
45364
|
+
if (existsSync9(join9(projectDir, file))) return manager;
|
|
45365
|
+
}
|
|
45366
|
+
return "npm";
|
|
45367
|
+
}
|
|
45368
|
+
function readScripts(projectDir) {
|
|
45369
|
+
const manifest = join9(projectDir, "package.json");
|
|
45370
|
+
if (!existsSync9(manifest)) return void 0;
|
|
45371
|
+
try {
|
|
45372
|
+
const parsed = JSON.parse(readFileSync7(manifest, "utf-8"));
|
|
45373
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
45374
|
+
const scripts = parsed.scripts;
|
|
45375
|
+
if (typeof scripts !== "object" || scripts === null) return void 0;
|
|
45376
|
+
const out = {};
|
|
45377
|
+
for (const [name, body] of Object.entries(scripts)) {
|
|
45378
|
+
if (typeof body === "string") out[name] = body;
|
|
45379
|
+
}
|
|
45380
|
+
return out;
|
|
45381
|
+
} catch {
|
|
45382
|
+
return void 0;
|
|
45383
|
+
}
|
|
45384
|
+
}
|
|
45385
|
+
function resolveCheckCommand(projectDir, check) {
|
|
45386
|
+
const scripts = readScripts(projectDir);
|
|
45387
|
+
if (scripts === void 0) {
|
|
45388
|
+
return {
|
|
45389
|
+
kind: "unconfigured",
|
|
45390
|
+
reason: `no readable package.json in ${projectDir}, so the "${check}" script could not be resolved`
|
|
45391
|
+
};
|
|
45392
|
+
}
|
|
45393
|
+
const candidates = SCRIPT_CANDIDATES[check];
|
|
45394
|
+
const found = candidates.find((name) => (scripts[name] ?? "").trim() !== "");
|
|
45395
|
+
if (found === void 0) {
|
|
45396
|
+
return {
|
|
45397
|
+
kind: "unconfigured",
|
|
45398
|
+
reason: `no "${check}" script declared (looked for: ${candidates.join(", ")})`
|
|
45399
|
+
};
|
|
45400
|
+
}
|
|
45401
|
+
return {
|
|
45402
|
+
kind: "command",
|
|
45403
|
+
command: detectPackageManager(projectDir),
|
|
45404
|
+
args: ["run", "--silent", found],
|
|
45405
|
+
script: found
|
|
45406
|
+
};
|
|
45407
|
+
}
|
|
45408
|
+
|
|
45338
45409
|
// src/security/quality-gate.ts
|
|
45339
45410
|
async function runCommandCheck(name, command, args, cwd) {
|
|
45340
45411
|
const start = Date.now();
|
|
@@ -45359,17 +45430,31 @@ async function runCommandCheck(name, command, args, cwd) {
|
|
|
45359
45430
|
};
|
|
45360
45431
|
}
|
|
45361
45432
|
}
|
|
45433
|
+
function scriptedCheck(name, check, projectDir) {
|
|
45434
|
+
return async () => {
|
|
45435
|
+
const resolved = resolveCheckCommand(projectDir, check);
|
|
45436
|
+
if (resolved.kind === "unconfigured") {
|
|
45437
|
+
return {
|
|
45438
|
+
name,
|
|
45439
|
+
verdict: "skip",
|
|
45440
|
+
details: `Not run: ${resolved.reason}. Declare the script to enable this check.`,
|
|
45441
|
+
durationMs: 0
|
|
45442
|
+
};
|
|
45443
|
+
}
|
|
45444
|
+
return runCommandCheck(name, resolved.command, resolved.args, projectDir);
|
|
45445
|
+
};
|
|
45446
|
+
}
|
|
45362
45447
|
function checkTypeCheck(projectDir) {
|
|
45363
|
-
return (
|
|
45448
|
+
return scriptedCheck("type_check", "typecheck", projectDir);
|
|
45364
45449
|
}
|
|
45365
45450
|
function checkLint(projectDir) {
|
|
45366
|
-
return (
|
|
45451
|
+
return scriptedCheck("lint", "lint", projectDir);
|
|
45367
45452
|
}
|
|
45368
45453
|
function checkTests(projectDir) {
|
|
45369
|
-
return (
|
|
45454
|
+
return scriptedCheck("tests", "tests", projectDir);
|
|
45370
45455
|
}
|
|
45371
45456
|
function checkBuild(projectDir) {
|
|
45372
|
-
return (
|
|
45457
|
+
return scriptedCheck("build", "build", projectDir);
|
|
45373
45458
|
}
|
|
45374
45459
|
function aggregateResults2(checks) {
|
|
45375
45460
|
let pass = 0;
|
|
@@ -45380,14 +45465,23 @@ function aggregateResults2(checks) {
|
|
|
45380
45465
|
else if (c.verdict === "fail") fail++;
|
|
45381
45466
|
else skip2++;
|
|
45382
45467
|
}
|
|
45383
|
-
|
|
45468
|
+
const verdict = fail > 0 ? "fail" : pass === 0 && skip2 > 0 ? "skip" : "pass";
|
|
45469
|
+
return { verdict, summary: { pass, fail, skip: skip2 } };
|
|
45384
45470
|
}
|
|
45385
45471
|
function generateFeedback2(checks) {
|
|
45386
45472
|
const failures = checks.filter((c) => c.verdict === "fail");
|
|
45387
|
-
|
|
45473
|
+
const skipped = checks.filter((c) => c.verdict === "skip");
|
|
45474
|
+
const skipNote = skipped.length > 0 ? `
|
|
45475
|
+
${String(skipped.length)} check(s) did not run:
|
|
45476
|
+
${skipped.map((s) => `- ${s.name}: ${s.details}`).join("\n")}` : "";
|
|
45477
|
+
if (failures.length === 0) {
|
|
45478
|
+
const ran = checks.length - skipped.length;
|
|
45479
|
+
const headline = ran === 0 ? "No checks ran." : `All ${String(ran)} check(s) that ran passed.`;
|
|
45480
|
+
return `${headline}${skipNote}`;
|
|
45481
|
+
}
|
|
45388
45482
|
const lines = failures.map((f) => `- ${f.name}: ${f.details}`);
|
|
45389
45483
|
return `${String(failures.length)} check(s) failed:
|
|
45390
|
-
${lines.join("\n")}`;
|
|
45484
|
+
${lines.join("\n")}${skipNote}`;
|
|
45391
45485
|
}
|
|
45392
45486
|
async function runQualityGate(stage, checks, iteration = 1) {
|
|
45393
45487
|
const results = [];
|
|
@@ -46210,7 +46304,7 @@ function createScaffoldStageWrapper() {
|
|
|
46210
46304
|
}
|
|
46211
46305
|
async function searchCodebaseForTask(task) {
|
|
46212
46306
|
try {
|
|
46213
|
-
const { CodebaseIndex: CodebaseIndex2 } = await import("./codebase-search-
|
|
46307
|
+
const { CodebaseIndex: CodebaseIndex2 } = await import("./codebase-search-AATGEN2H.js");
|
|
46214
46308
|
const index = new CodebaseIndex2(process.cwd());
|
|
46215
46309
|
const terms = task.toLowerCase().split(/\s+/).filter((w) => w.length > 4).slice(0, 3);
|
|
46216
46310
|
if (terms.length === 0) return null;
|
|
@@ -46447,8 +46541,8 @@ function reviewedDiffWasTruncated(diff) {
|
|
|
46447
46541
|
}
|
|
46448
46542
|
|
|
46449
46543
|
// src/audit/pr-review-record-store.ts
|
|
46450
|
-
import { appendFileSync as appendFileSync4, existsSync as
|
|
46451
|
-
import { dirname as dirname4, isAbsolute, join as
|
|
46544
|
+
import { appendFileSync as appendFileSync4, existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync8 } from "fs";
|
|
46545
|
+
import { dirname as dirname4, isAbsolute, join as join10, resolve as resolve13 } from "path";
|
|
46452
46546
|
|
|
46453
46547
|
// src/audit/pr-review-record.ts
|
|
46454
46548
|
import * as crypto3 from "crypto";
|
|
@@ -46579,7 +46673,7 @@ function assertNotSourceCheckoutWrite(filePath) {
|
|
|
46579
46673
|
if (!isUnderTestRunner()) return;
|
|
46580
46674
|
const here = findRepoRoot(process.cwd());
|
|
46581
46675
|
if (here === null) return;
|
|
46582
|
-
if (resolve13(filePath) !== resolve13(
|
|
46676
|
+
if (resolve13(filePath) !== resolve13(join10(here, PR_REVIEW_RECORDS_REL_PATH))) return;
|
|
46583
46677
|
throw new Error(
|
|
46584
46678
|
`Refusing to write ${filePath} from a test run (#4415): this is the source checkout's tracked, hash-chained audit file, and a fabricated record that chains cleanly is indistinguishable from a real verdict. Pass repoPath to a throwaway repo, or set NEXUS_PR_REVIEW_RECORDS_PATH.`
|
|
46585
46679
|
);
|
|
@@ -46591,17 +46685,17 @@ function resolvePrReviewRecordsPath(repoPathOverride) {
|
|
|
46591
46685
|
}
|
|
46592
46686
|
if (repoPathOverride !== void 0 && repoPathOverride.trim() !== "") {
|
|
46593
46687
|
const overrideRoot = findRepoRoot(repoPathOverride);
|
|
46594
|
-
if (overrideRoot !== null) return
|
|
46688
|
+
if (overrideRoot !== null) return join10(overrideRoot, PR_REVIEW_RECORDS_REL_PATH);
|
|
46595
46689
|
}
|
|
46596
46690
|
const root = findRepoRoot(process.cwd());
|
|
46597
46691
|
if (root === null) return void 0;
|
|
46598
|
-
return
|
|
46692
|
+
return join10(root, PR_REVIEW_RECORDS_REL_PATH);
|
|
46599
46693
|
}
|
|
46600
46694
|
function readPrReviewRecords(filePath) {
|
|
46601
46695
|
const records = [];
|
|
46602
46696
|
const invalidLines = [];
|
|
46603
|
-
if (!
|
|
46604
|
-
const lines =
|
|
46697
|
+
if (!existsSync10(filePath)) return { records, invalidLines };
|
|
46698
|
+
const lines = readFileSync8(filePath, "utf-8").split("\n").filter((l) => l.trim() !== "");
|
|
46605
46699
|
for (const [i, line] of lines.entries()) {
|
|
46606
46700
|
try {
|
|
46607
46701
|
const parsed = PrReviewRecordSchema.safeParse(JSON.parse(line));
|
|
@@ -46614,7 +46708,7 @@ function readPrReviewRecords(filePath) {
|
|
|
46614
46708
|
return { records, invalidLines };
|
|
46615
46709
|
}
|
|
46616
46710
|
function readPrReviewLedgerTip(filePath, logger58) {
|
|
46617
|
-
if (!
|
|
46711
|
+
if (!existsSync10(filePath)) return { maxSequence: -1, lastHash: void 0 };
|
|
46618
46712
|
try {
|
|
46619
46713
|
const { records } = readPrReviewRecords(filePath);
|
|
46620
46714
|
if (records.length === 0) return { maxSequence: -1, lastHash: void 0 };
|
|
@@ -47847,7 +47941,7 @@ function registerQueryTaskStateTool(server, deps) {
|
|
|
47847
47941
|
import { z as z100 } from "zod";
|
|
47848
47942
|
|
|
47849
47943
|
// src/mcp/tools/ci-health-log.ts
|
|
47850
|
-
import { appendFileSync as appendFileSync5, existsSync as
|
|
47944
|
+
import { appendFileSync as appendFileSync5, existsSync as existsSync12, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
47851
47945
|
import { z as z99 } from "zod";
|
|
47852
47946
|
|
|
47853
47947
|
// src/mcp/tools/ci-health-types.ts
|
|
@@ -47889,7 +47983,7 @@ function capLogSize(path12) {
|
|
|
47889
47983
|
}
|
|
47890
47984
|
if (size <= max) return;
|
|
47891
47985
|
try {
|
|
47892
|
-
const lines =
|
|
47986
|
+
const lines = readFileSync10(path12, "utf-8").split("\n").filter((l) => l !== "");
|
|
47893
47987
|
const kept = [];
|
|
47894
47988
|
let bytes = 0;
|
|
47895
47989
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -48692,7 +48786,7 @@ function createMetaOrchestrator(options) {
|
|
|
48692
48786
|
}
|
|
48693
48787
|
|
|
48694
48788
|
// src/orchestration/meta-shadow-selector.ts
|
|
48695
|
-
import { appendFileSync as appendFileSync6, existsSync as
|
|
48789
|
+
import { appendFileSync as appendFileSync6, existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
|
|
48696
48790
|
import { z as z104 } from "zod";
|
|
48697
48791
|
var SHADOW_STRATEGY_ARMS = [
|
|
48698
48792
|
"single-shot",
|
|
@@ -48811,11 +48905,11 @@ function hydrateShadowSelector(selector) {
|
|
|
48811
48905
|
const hydratable = selector;
|
|
48812
48906
|
if (typeof hydratable.recordFromContext !== "function") return 0;
|
|
48813
48907
|
const file = getMetaOutcomesFile();
|
|
48814
|
-
if (!
|
|
48908
|
+
if (!existsSync13(file)) return 0;
|
|
48815
48909
|
let replayed = 0;
|
|
48816
48910
|
try {
|
|
48817
48911
|
const cutoff = Date.now() - HYDRATE_LOOKBACK_MS;
|
|
48818
|
-
const lines =
|
|
48912
|
+
const lines = readFileSync11(file, "utf-8").split("\n").filter((l) => l.trim().length > 0);
|
|
48819
48913
|
for (const line of lines) {
|
|
48820
48914
|
let parsed;
|
|
48821
48915
|
try {
|
|
@@ -54163,4 +54257,4 @@ export {
|
|
|
54163
54257
|
shutdownFeedbackSubscriber,
|
|
54164
54258
|
createEventBusBridge
|
|
54165
54259
|
};
|
|
54166
|
-
//# sourceMappingURL=chunk-
|
|
54260
|
+
//# sourceMappingURL=chunk-W7532ZQG.js.map
|