Function bodies 205 total
prepareToolCall function · javascript · L48-L104 (57 LOC)cli/agent.js
async function prepareToolCall(tc) {
const fnName = tc.function.name;
const args = parseToolArgs(tc.function.arguments);
const callId = tc.id || `cli-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
// Malformed args
if (!args) {
const allToolDefs = [...TOOL_DEFINITIONS, ...getSkillToolDefinitions(), ...getMCPToolDefinitions()];
const toolDef = allToolDefs.find(t => t.function.name === fnName);
const schema = toolDef ? JSON.stringify(toolDef.function.parameters, null, 2) : 'unknown';
console.log(`${C.yellow} ⚠ ${fnName}: malformed arguments, sending schema hint${C.reset}`);
return {
callId, fnName, args: null, canExecute: false,
errorResult: {
role: 'tool',
content: `ERROR: Malformed tool arguments. Could not parse your arguments as JSON.\n` +
`Raw input: ${typeof tc.function.arguments === 'string' ? tc.function.arguments.substring(0, 200) : 'N/A'}\n\n` +
`Expected JSON schema for "${fnName}":\n${sexecuteToolRouted function · javascript · L109-L115 (7 LOC)cli/agent.js
async function executeToolRouted(fnName, args, options = {}) {
const skillResult = await routeSkillCall(fnName, args);
if (skillResult !== null) return skillResult;
const mcpResult = await routeMCPCall(fnName, args);
if (mcpResult !== null) return mcpResult;
return executeTool(fnName, args, options);
}_argPreview function · javascript · L120-L136 (17 LOC)cli/agent.js
function _argPreview(name, args) {
switch (name) {
case 'read_file': case 'write_file': case 'edit_file':
case 'patch_file': case 'list_directory':
return args.path || '';
case 'bash':
return (args.command || '').substring(0, 60);
case 'grep': case 'search_files': case 'glob':
return args.pattern || '';
case 'web_fetch':
return (args.url || '').substring(0, 50);
case 'web_search':
return (args.query || '').substring(0, 40);
default:
return '';
}
}executeSingleTool function · javascript · L142-L165 (24 LOC)cli/agent.js
async function executeSingleTool(prep, quiet = false) {
if (!quiet) {
console.log(formatToolCall(prep.fnName, prep.args));
}
runHooks('pre-tool', { tool_name: prep.fnName });
const toolResult = await executeToolRouted(prep.fnName, prep.args, { silent: true });
const safeResult = String(toolResult ?? '');
const truncated = safeResult.length > 50000
? safeResult.substring(0, 50000) + `\n...(truncated ${safeResult.length - 50000} chars)`
: safeResult;
if (!quiet) {
console.log(formatResult(truncated));
}
runHooks('post-tool', { tool_name: prep.fnName });
const isError = truncated.startsWith('ERROR') || truncated.includes('CANCELLED') || truncated.includes('BLOCKED');
const summary = formatToolSummary(prep.fnName, prep.args, truncated, isError);
const msg = { role: 'tool', content: truncated, tool_call_id: prep.callId };
return { msg, summary };
}executeBatch function · javascript · L172-L242 (71 LOC)cli/agent.js
async function executeBatch(prepared, quiet = false) {
const results = new Array(prepared.length);
const summaries = [];
let batch = [];
// Quiet mode: show a single spinner for all tools
let spinner = null;
if (quiet) {
const execTools = prepared.filter(p => p.canExecute);
if (execTools.length > 0) {
let label;
if (execTools.length === 1) {
const p = execTools[0];
label = `▸ ${p.fnName} ${_argPreview(p.fnName, p.args)}`;
} else {
const names = execTools.map(p => p.fnName).join(', ');
label = `▸ ${execTools.length} tools: ${names.length > 60 ? names.substring(0, 57) + '...' : names}`;
}
spinner = new Spinner(label);
spinner.start();
}
}
async function flushBatch() {
if (batch.length === 0) return;
if (batch.length === 1) {
const idx = batch[0];
const { msg, summary } = await executeSingleTool(prepared[idx], quiet);
results[idx] = msg;
summaries.push(summary)flushBatch function · javascript · L195-L211 (17 LOC)cli/agent.js
async function flushBatch() {
if (batch.length === 0) return;
if (batch.length === 1) {
const idx = batch[0];
const { msg, summary } = await executeSingleTool(prepared[idx], quiet);
results[idx] = msg;
summaries.push(summary);
} else {
const promises = batch.map(idx => executeSingleTool(prepared[idx], quiet));
const batchResults = await Promise.all(promises);
for (let j = 0; j < batch.length; j++) {
results[batch[j]] = batchResults[j].msg;
summaries.push(batchResults[j].summary);
}
}
batch = [];
}buildSystemPrompt function · javascript · L247-L329 (83 LOC)cli/agent.js
function buildSystemPrompt() {
const projectContext = gatherProjectContext(CWD);
const memoryContext = getMemoryContext();
const skillInstructions = getSkillInstructions();
const planPrompt = isPlanMode() ? getPlanModePrompt() : '';
return `You are Nex Code, an expert coding assistant. You help with programming tasks by reading, writing, and editing files, running commands, and answering questions.
WORKING DIRECTORY: ${CWD}
All relative paths resolve from this directory.
PROJECT CONTEXT:
${projectContext}
${memoryContext ? `\n${memoryContext}\n` : ''}${skillInstructions ? `\n${skillInstructions}\n` : ''}${planPrompt ? `\n${planPrompt}\n` : ''}
# Core Behavior
- You can use tools OR respond with text. For simple questions, answer directly.
- For coding tasks, use tools to read files, make changes, run tests, etc.
- Be concise. Keep responses short and focused.
- When referencing code, include file:line (e.g. src/app.js:42) so the user can navigate.
- Do not make up file pRepobility · MCP-ready · https://repobility.com
_printResume function · javascript · L351-L366 (16 LOC)cli/agent.js
function _printResume(totalSteps, toolCounts, filesModified) {
if (totalSteps < 1) return;
const totalTools = [...toolCounts.values()].reduce((a, b) => a + b, 0);
let resume = `── ${totalSteps} ${totalSteps === 1 ? 'step' : 'steps'} · ${totalTools} ${totalTools === 1 ? 'tool' : 'tools'}`;
if (filesModified.size > 0) {
resume += ` · ${filesModified.size} ${filesModified.size === 1 ? 'file' : 'files'} modified`;
}
resume += ' ──';
console.log(`\n${C.dim} ${resume}${C.reset}`);
// Follow-up suggestions (only when files were modified)
if (filesModified.size > 0) {
console.log(`${C.dim} 💡 /diff · /commit · /undo${C.reset}`);
}
}processInput function · javascript · L372-L525 (154 LOC)cli/agent.js
async function processInput(userInput) {
conversationMessages.push({ role: 'user', content: userInput });
const systemPrompt = buildSystemPrompt();
const fullMessages = [{ role: 'system', content: systemPrompt }, ...conversationMessages];
// Context-aware compression: fit messages into context window
const { messages: fittedMessages, compressed, tokensRemoved } = fitToContext(
fullMessages,
TOOL_DEFINITIONS
);
if (compressed) {
console.log(`${C.dim} [context compressed, ~${tokensRemoved} tokens freed]${C.reset}`);
}
// Context budget warning
const usage = getUsage(fullMessages, TOOL_DEFINITIONS);
if (usage.percentage > 85) {
console.log(`${C.yellow} ⚠ Context ${Math.round(usage.percentage)}% full — consider /clear or /save + start fresh${C.reset}`);
}
// Use fitted messages for the API call, but keep fullMessages reference for appending
let apiMessages = fittedMessages;
let rateLimitRetries = 0;
// ─── Stats tracking for résumé ──getTokenRatio function · javascript · L24-L32 (9 LOC)cli/context-engine.js
function getTokenRatio() {
try {
const model = getActiveModel();
const provider = model?.provider || 'ollama';
return TOKEN_RATIOS[provider] || 4.0;
} catch {
return 4.0;
}
}estimateMessageTokens function · javascript · L48-L70 (23 LOC)cli/context-engine.js
function estimateMessageTokens(msg) {
const MESSAGE_OVERHEAD = 4;
let tokens = MESSAGE_OVERHEAD;
if (msg.content) {
tokens += estimateTokens(msg.content);
}
if (msg.tool_calls) {
for (const tc of msg.tool_calls) {
tokens += 4; // tool call overhead
tokens += estimateTokens(tc.function?.name || '');
const args = tc.function?.arguments;
if (typeof args === 'string') {
tokens += estimateTokens(args);
} else if (args) {
tokens += estimateTokens(JSON.stringify(args));
}
}
}
return tokens;
}estimateMessagesTokens function · javascript · L75-L81 (7 LOC)cli/context-engine.js
function estimateMessagesTokens(messages) {
let total = 0;
for (const msg of messages) {
total += estimateMessageTokens(msg);
}
return total;
}getUsage function · javascript · L108-L143 (36 LOC)cli/context-engine.js
function getUsage(messages, tools) {
const messageTokens = estimateMessagesTokens(messages);
const toolTokens = estimateToolsTokens(tools);
const used = messageTokens + toolTokens;
const limit = getContextWindow();
const percentage = limit > 0 ? (used / limit) * 100 : 0;
// Breakdown
let systemTokens = 0;
let conversationTokens = 0;
let toolResultTokens = 0;
for (const msg of messages) {
const t = estimateMessageTokens(msg);
if (msg.role === 'system') {
systemTokens += t;
} else if (msg.role === 'tool') {
toolResultTokens += t;
} else {
conversationTokens += t;
}
}
return {
used,
limit,
percentage: Math.round(percentage * 10) / 10,
breakdown: {
system: systemTokens,
conversation: conversationTokens,
toolResults: toolResultTokens,
toolDefinitions: toolTokens,
},
messageCount: messages.length,
};
}compressMessage function · javascript · L158-L200 (43 LOC)cli/context-engine.js
function compressMessage(msg, level = 'light') {
const maxContent = level === 'aggressive' ? 100 : TRUNCATE_ASSISTANT;
const maxTool = level === 'aggressive' ? 50 : TRUNCATE_TOOL_RESULT;
if (msg.role === 'tool') {
const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
if (content.length > maxTool) {
return {
...msg,
content: content.substring(0, maxTool) + `\n...(truncated, was ${content.length} chars)`,
};
}
return msg;
}
if (msg.role === 'assistant') {
const compressed = { ...msg };
// Truncate long content
if (compressed.content && compressed.content.length > maxContent) {
compressed.content =
compressed.content.substring(0, maxContent) + `\n...(truncated)`;
}
// Simplify tool_calls in old messages
if (compressed.tool_calls && level === 'aggressive') {
compressed.tool_calls = compressed.tool_calls.map((tc) => ({
...tc,
function: fitToContext function · javascript · L217-L288 (72 LOC)cli/context-engine.js
function fitToContext(messages, tools, options = {}) {
const threshold = options.threshold ?? COMPRESSION_THRESHOLD;
const keepRecent = options.keepRecent ?? KEEP_RECENT;
const limit = getContextWindow();
const toolTokens = estimateToolsTokens(tools);
const targetMax = Math.floor(limit * threshold);
const available = targetMax - toolTokens;
const currentTokens = estimateMessagesTokens(messages);
const totalUsed = currentTokens + toolTokens;
// Under threshold → no compression needed
if (totalUsed <= targetMax) {
return { messages, compressed: false, tokensRemoved: 0 };
}
const originalTokens = currentTokens;
// Split: system + old messages + recent messages
let system = null;
let startIdx = 0;
if (messages.length > 0 && messages[0].role === 'system') {
system = messages[0];
startIdx = 1;
}
const recentStart = Math.max(startIdx, messages.length - keepRecent);
const oldMessages = messages.slice(startIdx, recentStart);
const recentProvenance: Repobility (https://repobility.com) — every score reproducible from /scan/
buildResult function · javascript · L290-L295 (6 LOC)cli/context-engine.js
function buildResult(system, oldMessages, recentMessages) {
const result = [];
if (system) result.push(system);
result.push(...oldMessages, ...recentMessages);
return result;
}truncateFileContent function · javascript · L307-L341 (35 LOC)cli/context-engine.js
function truncateFileContent(content, maxTokens) {
if (!content) return '';
const currentTokens = estimateTokens(content);
if (currentTokens <= maxTokens) return content;
const maxChars = maxTokens * 4; // Reverse the estimation
const lines = content.split('\n');
// Keep first 60% and last 40%
const headChars = Math.floor(maxChars * 0.6);
const tailChars = Math.floor(maxChars * 0.4);
let headContent = '';
let headLines = 0;
for (const line of lines) {
if (headContent.length + line.length + 1 > headChars) break;
headContent += (headContent ? '\n' : '') + line;
headLines++;
}
let tailContent = '';
let tailLines = 0;
for (let i = lines.length - 1; i >= headLines; i--) {
const candidate = lines[i] + (tailContent ? '\n' : '') + tailContent;
if (candidate.length > tailChars) break;
tailContent = candidate;
tailLines++;
}
const skipped = lines.length - headLines - tailLines;
const separator = `\n\n... (${skipped} lines omitsafe function · javascript · L10-L16 (7 LOC)cli/context.js
function safe(fn) {
try {
return fn();
} catch {
return null;
}
}gatherProjectContext function · javascript · L18-L61 (44 LOC)cli/context.js
function gatherProjectContext(cwd) {
const parts = [];
// package.json
const pkgPath = path.join(cwd, 'package.json');
if (fs.existsSync(pkgPath)) {
try {
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
const info = { name: pkg.name, version: pkg.version };
if (pkg.scripts) info.scripts = Object.keys(pkg.scripts).slice(0, 15);
if (pkg.dependencies) info.deps = Object.keys(pkg.dependencies).length;
if (pkg.devDependencies) info.devDeps = Object.keys(pkg.devDependencies).length;
parts.push(`PACKAGE: ${JSON.stringify(info)}`);
} catch { /* ignore corrupt package.json */ }
}
// README (first 50 lines)
const readmePath = path.join(cwd, 'README.md');
if (fs.existsSync(readmePath)) {
const lines = fs.readFileSync(readmePath, 'utf-8').split('\n').slice(0, 50);
parts.push(`README (first 50 lines):\n${lines.join('\n')}`);
}
// Git info
const branch = safe(() => execSync('git branch --show-current', { cwd, encprintContext function · javascript · L63-L79 (17 LOC)cli/context.js
function printContext(cwd) {
const pkgPath = path.join(cwd, 'package.json');
let project = '';
if (fs.existsSync(pkgPath)) {
try {
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
project = `${pkg.name || '?'} v${pkg.version || '?'}`;
} catch { /* ignore corrupt package.json */ }
}
const branch = safe(() => execSync('git branch --show-current', { cwd, encoding: 'utf-8', stdio: 'pipe' }).trim());
console.log(`${C.dim} cwd: ${cwd}${C.reset}`);
if (project) console.log(`${C.dim} project: ${project}${C.reset}`);
if (branch) console.log(`${C.dim} branch: ${branch}${C.reset}`);
console.log();
}getSessionCosts function · javascript · L78-L100 (23 LOC)cli/costs.js
function getSessionCosts() {
const byKey = {};
for (const entry of usageLog) {
const key = `${entry.provider}:${entry.model}`;
if (!byKey[key]) {
byKey[key] = { provider: entry.provider, model: entry.model, input: 0, output: 0 };
}
byKey[key].input += entry.input;
byKey[key].output += entry.output;
}
const breakdown = Object.values(byKey).map((b) => ({
...b,
cost: calcCost(b),
}));
const totalCost = breakdown.reduce((sum, b) => sum + b.cost, 0);
const totalInput = breakdown.reduce((sum, b) => sum + b.input, 0);
const totalOutput = breakdown.reduce((sum, b) => sum + b.output, 0);
return { totalCost, totalInput, totalOutput, breakdown };
}formatCosts function · javascript · L106-L129 (24 LOC)cli/costs.js
function formatCosts() {
const { totalCost, totalInput, totalOutput, breakdown } = getSessionCosts();
if (breakdown.length === 0) {
return 'No token usage recorded this session.';
}
const lines = [];
lines.push('Session Token Usage:');
lines.push('');
for (const b of breakdown) {
const costStr = b.cost > 0 ? `$${b.cost.toFixed(4)}` : 'free';
lines.push(` ${b.provider}:${b.model}`);
lines.push(` Input: ${b.input.toLocaleString()} tokens`);
lines.push(` Output: ${b.output.toLocaleString()} tokens`);
lines.push(` Cost: ${costStr}`);
}
lines.push('');
lines.push(` Total: ${totalInput.toLocaleString()} in + ${totalOutput.toLocaleString()} out = $${totalCost.toFixed(4)}`);
return lines.join('\n');
}formatCostHint function · javascript · L135-L140 (6 LOC)cli/costs.js
function formatCostHint(provider, model, inputTokens, outputTokens) {
const pricing = getPricing(provider, model);
const cost = (inputTokens * pricing.input + outputTokens * pricing.output) / 1_000_000;
if (cost <= 0) return '';
return `[~$${cost.toFixed(4)}]`;
}Repobility · severity-and-effort ranking · https://repobility.com
diffLines function · javascript · L15-L60 (46 LOC)cli/diff.js
function diffLines(oldText, newText) {
const oldLines = oldText.split('\n');
const newLines = newText.split('\n');
const result = [];
// Guard against OOM on huge files — fall back to simple summary
const m = oldLines.length;
const n = newLines.length;
if (m > DIFF_LINE_LIMIT || n > DIFF_LINE_LIMIT) {
// Produce a simplified diff: all old lines removed, all new lines added
for (const line of oldLines) result.push({ type: 'remove', line });
for (const line of newLines) result.push({ type: 'add', line });
return result;
}
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (oldLines[i - 1] === newLines[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// Backtrack
let i = m,
j = n;
const ops = [];
while (i > 0 || j > 0) {
if (i > 0 && j > 0 && oldLishowEditDiff function · javascript · L65-L101 (37 LOC)cli/diff.js
function showEditDiff(filePath, oldText, newText, contextLines = 3) {
console.log(`\n${C.bold}${C.cyan} Diff: ${filePath}${C.reset}`);
const ops = diffLines(oldText, newText);
// Find changed regions and show with context
const changed = [];
ops.forEach((op, idx) => {
if (op.type !== 'same') changed.push(idx);
});
if (changed.length === 0) {
console.log(`${C.gray} (no changes)${C.reset}`);
return;
}
const showFrom = Math.max(0, changed[0] - contextLines);
const showTo = Math.min(ops.length, changed[changed.length - 1] + contextLines + 1);
if (showFrom > 0) console.log(`${C.gray} ...${C.reset}`);
for (let k = showFrom; k < showTo; k++) {
const op = ops[k];
switch (op.type) {
case 'remove':
console.log(`${C.red} - ${op.line}${C.reset}`);
break;
case 'add':
console.log(`${C.green} + ${op.line}${C.reset}`);
break;
default:
console.log(`${C.gray} ${op.line}${C.reset}`);
showWriteDiff function · javascript · L106-L144 (39 LOC)cli/diff.js
function showWriteDiff(filePath, oldContent, newContent) {
console.log(`\n${C.bold}${C.cyan} File exists — showing changes: ${filePath}${C.reset}`);
const ops = diffLines(oldContent, newContent);
let changes = 0;
for (const op of ops) {
if (op.type !== 'same') changes++;
}
if (changes === 0) {
console.log(`${C.gray} (identical content)${C.reset}`);
return;
}
// Show up to 30 diff lines
let shown = 0;
for (const op of ops) {
if (shown >= 30) {
console.log(`${C.gray} ...(${changes - shown} more changes)${C.reset}`);
break;
}
switch (op.type) {
case 'remove':
console.log(`${C.red} - ${op.line}${C.reset}`);
shown++;
break;
case 'add':
console.log(`${C.green} + ${op.line}${C.reset}`);
shown++;
break;
default:
if (shown > 0) {
// Only show context around changes
console.log(`${C.gray} ${op.line}${C.reset}`);
}
}
}
showNewFilePreview function · javascript · L149-L160 (12 LOC)cli/diff.js
function showNewFilePreview(filePath, content) {
console.log(`\n${C.bold}${C.cyan} New file: ${filePath}${C.reset}`);
const lines = content.split('\n');
const preview = lines.slice(0, 20);
for (const line of preview) {
console.log(`${C.green} + ${line}${C.reset}`);
}
if (lines.length > 20) {
console.log(`${C.gray} ...+${lines.length - 20} more lines${C.reset}`);
}
console.log();
}showSideBySideDiff function · javascript · L177-L249 (73 LOC)cli/diff.js
function showSideBySideDiff(filePath, oldText, newText, width) {
const termWidth = width || process.stdout.columns || 80;
const colWidth = Math.floor((termWidth - 3) / 2); // 3 for separator "│"
console.log(`\n${C.bold}${C.cyan} Side-by-side: ${filePath}${C.reset}`);
console.log(` ${C.dim}${'─'.repeat(colWidth)}┬${'─'.repeat(colWidth)}${C.reset}`);
const ops = diffLines(oldText, newText);
// Pair up removals and additions
const pairs = [];
let i = 0;
while (i < ops.length) {
if (ops[i].type === 'same') {
pairs.push({ left: ops[i].line, right: ops[i].line, type: 'same' });
i++;
} else if (ops[i].type === 'remove') {
// Collect consecutive removes, then matching adds
const removes = [];
while (i < ops.length && ops[i].type === 'remove') {
removes.push(ops[i].line);
i++;
}
const adds = [];
while (i < ops.length && ops[i].type === 'add') {
adds.push(ops[i].line);
i++;
}
recordChange function · javascript · L19-L31 (13 LOC)cli/file-history.js
function recordChange(tool, filePath, oldContent, newContent) {
undoStack.push({
tool,
filePath,
oldContent,
newContent,
timestamp: Date.now(),
});
// Trim to max history
while (undoStack.length > MAX_HISTORY) undoStack.shift();
// New edit clears redo stack
redoStack.length = 0;
}undo function · javascript · L37-L54 (18 LOC)cli/file-history.js
function undo() {
if (undoStack.length === 0) return null;
const entry = undoStack.pop();
if (entry.oldContent === null) {
// File was newly created — delete it
try { fs.unlinkSync(entry.filePath); } catch { /* ignore */ }
} else {
fs.writeFileSync(entry.filePath, entry.oldContent, 'utf-8');
}
redoStack.push(entry);
return {
tool: entry.tool,
filePath: entry.filePath,
wasCreated: entry.oldContent === null,
};
}redo function · javascript · L60-L71 (12 LOC)cli/file-history.js
function redo() {
if (redoStack.length === 0) return null;
const entry = redoStack.pop();
fs.writeFileSync(entry.filePath, entry.newContent, 'utf-8');
undoStack.push(entry);
return {
tool: entry.tool,
filePath: entry.filePath,
};
}Repobility · open methodology · https://repobility.com/research/
getHistory function · javascript · L78-L84 (7 LOC)cli/file-history.js
function getHistory(limit = 10) {
return undoStack.slice(-limit).reverse().map((e) => ({
tool: e.tool,
filePath: e.filePath,
timestamp: e.timestamp,
}));
}normalizeWhitespace function · javascript · L16-L33 (18 LOC)cli/fuzzy-match.js
function normalizeWhitespace(text) {
return text
.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n')
.replace(/\t/g, ' ')
.split('\n')
.map(line => {
// Trim trailing whitespace
line = line.replace(/\s+$/, '');
// Collapse multiple inline spaces (preserve leading indentation)
const match = line.match(/^(\s*)(.*)/);
if (!match) return line;
const indent = match[1];
const rest = match[2].replace(/ {2,}/g, ' ');
return indent + rest;
})
.join('\n');
}fuzzyFindText function · javascript · L44-L90 (47 LOC)cli/fuzzy-match.js
function fuzzyFindText(haystack, needle) {
// Fast path: exact match
if (haystack.includes(needle)) return needle;
const normHaystack = normalizeWhitespace(haystack);
const normNeedle = normalizeWhitespace(needle);
if (!normHaystack.includes(normNeedle)) return null;
// Map normalized position back to original text using line-based matching
const haystackLines = haystack.split('\n');
const normHaystackLines = normHaystack.split('\n');
const normNeedleLines = normNeedle.split('\n');
// Find which normalized line the match starts on
const needleFirstLine = normNeedleLines[0];
const needleLastLine = normNeedleLines[normNeedleLines.length - 1];
for (let i = 0; i <= normHaystackLines.length - normNeedleLines.length; i++) {
// Check if this position matches in normalized form
let matches = true;
for (let j = 0; j < normNeedleLines.length; j++) {
if (normHaystackLines[i + j] !== normNeedleLines[j]) {
matches = false;
break;
findMostSimilar function · javascript · L100-L182 (83 LOC)cli/fuzzy-match.js
function findMostSimilar(content, target) {
if (!content || !target) return null;
const contentLines = content.split('\n');
const targetLines = target.split('\n');
const targetLineCount = targetLines.length;
if (contentLines.length === 0 || targetLineCount === 0) return null;
// For single-line targets, search line by line
if (targetLineCount === 1) {
let best = null;
let bestDist = Infinity;
// Sample lines if too many (max 200 candidates)
const step = Math.max(1, Math.floor(contentLines.length / 200));
for (let i = 0; i < contentLines.length; i += step) {
const line = contentLines[i];
if (!line.trim()) continue;
const dist = levenshtein(line.trim(), target.trim());
if (dist < bestDist) {
bestDist = dist;
best = { text: line, distance: dist, line: i + 1 };
}
}
// Refine: check neighbors of best match
if (best && step > 1) {
const center = best.line - 1;
const lo = Math.max(0, cexec function · javascript · L9-L15 (7 LOC)cli/git.js
function exec(cmd) {
try {
return execSync(cmd, { cwd: process.cwd(), encoding: 'utf-8', timeout: 30000, stdio: 'pipe' }).trim();
} catch (e) {
return null;
}
}execGit function · javascript · L17-L23 (7 LOC)cli/git.js
function execGit(...args) {
try {
return execFileSync('git', args, { cwd: process.cwd(), encoding: 'utf-8', timeout: 30000, stdio: 'pipe' }).trim();
} catch (e) {
return null;
}
}getStatus function · javascript · L42-L54 (13 LOC)cli/git.js
function getStatus() {
try {
const raw = execSync('git status --porcelain', { cwd: process.cwd(), encoding: 'utf-8', timeout: 30000, stdio: 'pipe' });
if (!raw || !raw.trim()) return [];
return raw.split('\n').filter(Boolean).map((line) => {
const status = line.substring(0, 2).trim();
const file = line.substring(3);
return { status, file };
});
} catch {
return [];
}
}analyzeDiff function · javascript · L77-L118 (42 LOC)cli/git.js
function analyzeDiff() {
const files = getChangedFiles();
if (files.length === 0) return null;
const diff = getDiff();
const stagedDiff = getDiff(true);
const fullDiff = stagedDiff || diff;
// Count additions/deletions from diff (if available)
let additions = 0;
let deletions = 0;
if (fullDiff) {
const lines = fullDiff.split('\n');
for (const line of lines) {
if (line.startsWith('+') && !line.startsWith('+++')) additions++;
if (line.startsWith('-') && !line.startsWith('---')) deletions++;
}
} else {
// Untracked files: count as additions
additions = files.length;
}
// Determine type based on files and content
let type = 'chore';
const fileNames = files.join(' ').toLowerCase();
if (fileNames.includes('test')) type = 'test';
else if (fileNames.includes('readme') || fileNames.includes('doc')) type = 'docs';
else if (additions > deletions * 2) type = 'feat';
else if (deletions > additions) type = 'refactor';
else typeRepobility · MCP-ready · https://repobility.com
createBranch function · javascript · L125-L135 (11 LOC)cli/git.js
function createBranch(description) {
const name = description
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.substring(0, 50);
const branchName = `feat/${name}`;
const result = execGit('checkout', '-b', branchName);
return result !== null ? branchName : null;
}commit function · javascript · L142-L147 (6 LOC)cli/git.js
function commit(message) {
execGit('add', '-A');
const result = execGit('commit', '-m', message);
if (!result) return null;
return execGit('rev-parse', '--short', 'HEAD');
}formatDiffSummary function · javascript · L152-L169 (18 LOC)cli/git.js
function formatDiffSummary() {
const analysis = analyzeDiff();
if (!analysis) return `${C.dim}No changes${C.reset}`;
const lines = [];
lines.push(`\n${C.bold}${C.cyan}Git Diff Summary:${C.reset}`);
lines.push(` ${C.green}+${analysis.stats.additions}${C.reset} ${C.red}-${analysis.stats.deletions}${C.reset} in ${analysis.files.length} file(s)`);
lines.push(`\n${C.bold}${C.cyan}Files:${C.reset}`);
for (const f of analysis.files.slice(0, 20)) {
lines.push(` ${C.dim}${f}${C.reset}`);
}
if (analysis.files.length > 20) {
lines.push(` ${C.dim}...+${analysis.files.length - 20} more${C.reset}`);
}
lines.push(`\n${C.bold}${C.cyan}Suggested message:${C.reset}`);
lines.push(` ${C.cyan}${analysis.summary}${C.reset}\n`);
return lines.join('\n');
}getDiffContext function · javascript · L175-L189 (15 LOC)cli/git.js
function getDiffContext() {
const files = getChangedFiles();
if (files.length === 0) return '';
const parts = [`CHANGED FILES (${files.length}):`];
for (const f of files.slice(0, 10)) {
parts.push(` ${f}`);
}
const diff = getDiff();
if (diff) {
const truncated = diff.length > 5000 ? diff.substring(0, 5000) + '\n...(truncated)' : diff;
parts.push(`\nDIFF:\n${truncated}`);
}
return parts.join('\n');
}loadHookConfig function · javascript · L35-L44 (10 LOC)cli/hooks.js
function loadHookConfig() {
const configPath = getConfigPath();
if (!fs.existsSync(configPath)) return {};
try {
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
return config.hooks || {};
} catch {
return {};
}
}getHooksForEvent function · javascript · L52-L72 (21 LOC)cli/hooks.js
function getHooksForEvent(event) {
if (!HOOK_EVENTS.includes(event)) return [];
const hooks = [];
// 1. Check .nex/hooks/{event} script
const hooksDir = getHooksDir();
const scriptPath = path.join(hooksDir, event);
if (fs.existsSync(scriptPath)) {
hooks.push(scriptPath);
}
// 2. Check .nex/config.json hooks
const config = loadHookConfig();
if (config[event]) {
const cmds = Array.isArray(config[event]) ? config[event] : [config[event]];
hooks.push(...cmds);
}
return hooks;
}executeHook function · javascript · L81-L97 (17 LOC)cli/hooks.js
function executeHook(command, env = {}, timeout = 30000) {
try {
const output = execSync(command, {
cwd: process.cwd(),
encoding: 'utf-8',
timeout,
env: { ...process.env, ...env },
stdio: ['pipe', 'pipe', 'pipe'],
});
return { success: true, output: output.trim() };
} catch (err) {
return {
success: false,
error: err.stderr ? err.stderr.trim() : err.message,
};
}
}runHooks function · javascript · L105-L127 (23 LOC)cli/hooks.js
function runHooks(event, context = {}) {
const hooks = getHooksForEvent(event);
if (hooks.length === 0) return [];
// Convert context to NEX_* env vars
const env = {};
for (const [key, value] of Object.entries(context)) {
env[`NEX_${key.toUpperCase()}`] = String(value);
}
const results = [];
for (const command of hooks) {
const result = executeHook(command, env);
results.push({ command, ...result });
// Stop on failure for pre-* hooks (they can block)
if (!result.success && event.startsWith('pre-')) {
break;
}
}
return results;
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
listHooks function · javascript · L142-L151 (10 LOC)cli/hooks.js
function listHooks() {
const result = [];
for (const event of HOOK_EVENTS) {
const commands = getHooksForEvent(event);
if (commands.length > 0) {
result.push({ event, commands });
}
}
return result;
}initHooksDir function · javascript · L156-L162 (7 LOC)cli/hooks.js
function initHooksDir() {
const dir = getHooksDir();
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
return dir;
}showCommandList function · javascript · L70-L82 (13 LOC)cli/index.js
function showCommandList() {
const skillCmds = getSkillCommands();
const allCmds = [...SLASH_COMMANDS, ...skillCmds];
const maxLen = Math.max(...allCmds.map((c) => c.cmd.length));
console.log('');
for (const { cmd, desc } of SLASH_COMMANDS) {
console.log(` ${C.cyan}${cmd.padEnd(maxLen + 2)}${C.reset}${C.dim}${desc}${C.reset}`);
}
for (const { cmd, desc } of skillCmds) {
console.log(` ${C.cyan}${cmd.padEnd(maxLen + 2)}${C.reset}${C.dim}${desc} ${C.yellow}[skill]${C.reset}`);
}
console.log(`\n${C.dim}Type /help for detailed usage${C.reset}\n`);
}page 1 / 5next ›