brainbank 0.9.5 → 0.9.6
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 +2 -2
- package/dist/cli.js +27 -15
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/mcp-export.ts +28 -18
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Extensions that connect BrainBank to external tools and workflows.
|
|
|
88
88
|
|
|
89
89
|
| Package | Description | Install |
|
|
90
90
|
|---------|-------------|----------|
|
|
91
|
-
| [`@brainbank/mcp`](packages/mcp/) | MCP server for Antigravity, Claude, Cursor | `npm i @brainbank/mcp` |
|
|
91
|
+
| [`@brainbank/mcp`](packages/mcp/) | MCP server for Antigravity, Claude, Cursor (read-only, 2 tools) | `npm i @brainbank/mcp` |
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
@@ -105,7 +105,7 @@ Extensions that connect BrainBank to external tools and workflows.
|
|
|
105
105
|
| **[Configuration](docs/config.md)** | `.brainbank/config.json`, env vars |
|
|
106
106
|
| **[Embeddings, Reranker & Pruner](docs/embeddings.md)** | Providers, benchmarks, per-plugin overrides, LLM noise filter |
|
|
107
107
|
| **[Multi-Repo](docs/multi-repo.md)** | Index multiple repositories into one DB |
|
|
108
|
-
| **[MCP Server](docs/mcp.md)** | AI tool integration (stdio) |
|
|
108
|
+
| **[MCP Server](docs/mcp.md)** | AI tool integration (stdio), `mcp:export` setup |
|
|
109
109
|
| **[Indexing](docs/indexing.md)** | Code graph, incremental indexing, re-embedding |
|
|
110
110
|
| **[Migrations](docs/migrations.md)** | Plugin schema migrations, built-in schemas |
|
|
111
111
|
| **[Architecture](docs/architecture.md)** | System internals, data flows, design patterns |
|
package/dist/cli.js
CHANGED
|
@@ -44,7 +44,7 @@ var TARGETS = {
|
|
|
44
44
|
label: "Gemini Antigravity"
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
function buildBrainbankMcpBlock(config
|
|
47
|
+
function buildBrainbankMcpBlock(config) {
|
|
48
48
|
const nodeBin = process.execPath;
|
|
49
49
|
const globalCliJs = path.join(path.dirname(nodeBin), "..", "lib", "node_modules", "brainbank", "dist", "cli.js");
|
|
50
50
|
const localCliJs = path.resolve(__dirname, "..", "..", "dist", "cli.js");
|
|
@@ -57,7 +57,6 @@ function buildBrainbankMcpBlock(config, repoPath) {
|
|
|
57
57
|
if (perplexityKey) env.PERPLEXITY_API_KEY = perplexityKey;
|
|
58
58
|
if (anthropicKey) env.ANTHROPIC_API_KEY = anthropicKey;
|
|
59
59
|
if (openaiKey) env.OPENAI_API_KEY = openaiKey;
|
|
60
|
-
env.BRAINBANK_REPO = path.resolve(repoPath);
|
|
61
60
|
const block = {
|
|
62
61
|
command: nodeBin,
|
|
63
62
|
args: ["--disable-warning=ExperimentalWarning", resolvedCliJs, "mcp"]
|
|
@@ -104,7 +103,7 @@ async function autoExportMcp(repoPath) {
|
|
|
104
103
|
if (!fs.existsSync(antigravityDir)) return;
|
|
105
104
|
if (hasBrainbankMcpEntry(target.configPath)) return;
|
|
106
105
|
const config = await getConfig(repoPath);
|
|
107
|
-
const block = buildBrainbankMcpBlock(config
|
|
106
|
+
const block = buildBrainbankMcpBlock(config);
|
|
108
107
|
mergeAndWrite(target.configPath, block);
|
|
109
108
|
console.log(` ${c.green("\u2713")} Exported MCP config to ${c.dim(path.relative(process.env.HOME ?? "", target.configPath))}`);
|
|
110
109
|
}
|
|
@@ -170,7 +169,7 @@ __name(replaceGeminiSection, "replaceGeminiSection");
|
|
|
170
169
|
async function cmdMcpExport() {
|
|
171
170
|
const targetName = args[1] || getFlag("target") || "antigravity";
|
|
172
171
|
const repoPath = getFlag("repo") || ".";
|
|
173
|
-
const
|
|
172
|
+
const force = args.includes("--force") || args.includes("-f");
|
|
174
173
|
const target = TARGETS[targetName];
|
|
175
174
|
if (!target) {
|
|
176
175
|
console.error(c.red(`Unknown export target: ${targetName}`));
|
|
@@ -178,18 +177,19 @@ async function cmdMcpExport() {
|
|
|
178
177
|
process.exit(1);
|
|
179
178
|
}
|
|
180
179
|
const config = await getConfig(repoPath);
|
|
181
|
-
const block = buildBrainbankMcpBlock(config
|
|
180
|
+
const block = buildBrainbankMcpBlock(config);
|
|
182
181
|
console.log(c.bold(`
|
|
183
182
|
\u2501\u2501\u2501 MCP Export: ${target.label} \u2501\u2501\u2501
|
|
184
183
|
`));
|
|
185
184
|
const mcpExists = hasBrainbankMcpEntry(target.configPath);
|
|
186
185
|
let writeMcp = true;
|
|
187
|
-
if (mcpExists) {
|
|
186
|
+
if (mcpExists && !force) {
|
|
188
187
|
console.log(` ${c.yellow("\u25CF")} MCP config already has brainbank entry`);
|
|
189
188
|
const cliPath = block.args.find((a) => !a.startsWith("--")) ?? block.args[0];
|
|
190
189
|
console.log(` ${c.dim(" New:")} ${block.command} ${cliPath}`);
|
|
191
190
|
const envKeys = block.env ? Object.keys(block.env) : [];
|
|
192
191
|
if (envKeys.length > 0) console.log(` ${c.dim(" Keys:")} ${envKeys.join(", ")}`);
|
|
192
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
193
193
|
writeMcp = await confirm({ message: "Override existing brainbank MCP entry?", default: true });
|
|
194
194
|
}
|
|
195
195
|
if (writeMcp) {
|
|
@@ -200,22 +200,34 @@ async function cmdMcpExport() {
|
|
|
200
200
|
}
|
|
201
201
|
const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);
|
|
202
202
|
if (geminiHasSection) {
|
|
203
|
-
|
|
204
|
-
const override = await confirm({ message: "Override existing BrainBank section?", default: false });
|
|
205
|
-
if (override) {
|
|
203
|
+
if (force) {
|
|
206
204
|
replaceGeminiSection(GLOBAL_GEMINI);
|
|
207
205
|
console.log(` ${c.green("\u2713")} Replaced BrainBank section in ${c.dim("~/.gemini/GEMINI.md")}`);
|
|
208
206
|
} else {
|
|
209
|
-
console.log(` ${c.
|
|
207
|
+
console.log(` ${c.yellow("\u25CF")} ~/.gemini/GEMINI.md already has BrainBank section`);
|
|
208
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
209
|
+
const override = await confirm({ message: "Override existing BrainBank section?", default: false });
|
|
210
|
+
if (override) {
|
|
211
|
+
replaceGeminiSection(GLOBAL_GEMINI);
|
|
212
|
+
console.log(` ${c.green("\u2713")} Replaced BrainBank section in ${c.dim("~/.gemini/GEMINI.md")}`);
|
|
213
|
+
} else {
|
|
214
|
+
console.log(` ${c.dim("GEMINI.md \u2014 skipped")}`);
|
|
215
|
+
}
|
|
210
216
|
}
|
|
211
217
|
} else {
|
|
212
|
-
|
|
213
|
-
message: "Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)",
|
|
214
|
-
default: true
|
|
215
|
-
});
|
|
216
|
-
if (addGemini) {
|
|
218
|
+
if (force) {
|
|
217
219
|
appendGeminiSection(GLOBAL_GEMINI);
|
|
218
220
|
console.log(` ${c.green("\u2713")} Added BrainBank section to ${c.dim("~/.gemini/GEMINI.md")}`);
|
|
221
|
+
} else {
|
|
222
|
+
const { confirm } = await import("@inquirer/prompts");
|
|
223
|
+
const addGemini = await confirm({
|
|
224
|
+
message: "Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)",
|
|
225
|
+
default: true
|
|
226
|
+
});
|
|
227
|
+
if (addGemini) {
|
|
228
|
+
appendGeminiSection(GLOBAL_GEMINI);
|
|
229
|
+
console.log(` ${c.green("\u2713")} Added BrainBank section to ${c.dim("~/.gemini/GEMINI.md")}`);
|
|
230
|
+
}
|
|
219
231
|
}
|
|
220
232
|
}
|
|
221
233
|
console.log(`
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/index.ts","../src/cli/commands/mcp-export.ts","../src/cli/commands/scan.ts","../src/cli/commands/collection.ts","../src/cli/commands/kv.ts","../src/cli/commands/docs.ts","../src/cli/commands/search.ts","../src/cli/server-client.ts","../src/cli/commands/context.ts","../src/cli/commands/files.ts","../src/cli/commands/stats.ts","../src/cli/commands/reembed.ts","../src/cli/commands/watch.ts","../src/cli/commands/mcp.ts","../src/cli/commands/daemon.ts","../src/cli/commands/status.ts","../src/cli/commands/help.ts","../src/cli/index.ts"],"sourcesContent":["/**\n * brainbank index [path] — Interactive scan → select → index\n *\n * Scans the repo first, shows a summary tree, and prompts the user\n * with checkboxes to select which modules to index. Use --yes to skip.\n */\n\nimport type { ScanResult, ScanModule } from './scan.ts';\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { c, args, getFlag, hasFlag, stripFlags } from '@/cli/utils.ts';\nimport { createBrain, getConfig, registerConfigCollections } from '@/cli/factory/index.ts';\nimport { findDocsPlugin } from '@/cli/utils.ts';\nimport { autoExportMcp } from './mcp-export.ts';\nimport { scanRepo } from './scan.ts';\n\nexport async function cmdIndex(): Promise<void> {\n const positional = stripFlags(args);\n const repoPath = positional[1] || '.';\n const force = hasFlag('force');\n const depth = parseInt(getFlag('depth') || '500', 10);\n const onlyRaw = getFlag('only');\n const docsPath = getFlag('docs');\n const skipPrompt = hasFlag('yes') || hasFlag('y');\n\n\n const scan = scanRepo(repoPath);\n printScanTree(scan, depth);\n\n\n let modules: string[];\n\n if (onlyRaw) {\n // --only flag: explicit module selection\n modules = onlyRaw.split(',').map(s => s.trim());\n } else if (scan.config.plugins && scan.config.plugins.length > 0) {\n // Config exists with plugins field — use it as source of truth\n modules = scan.config.plugins;\n console.log(c.dim(`\\n Using config: plugins = [${modules.join(', ')}]\\n`));\n } else if (skipPrompt) {\n modules = buildDefaultModules(scan);\n } else {\n modules = await promptModules(scan);\n if (modules.length === 0) {\n console.log(c.dim('\\n Nothing selected. Exiting.\\n'));\n return;\n }\n\n // Clean screen and show selection summary\n console.clear();\n console.log(c.bold('\\n━━━ BrainBank ━━━\\n'));\n console.log(' Selected modules:');\n for (const m of modules) {\n console.log(` ${c.green('✓')} ${m}`);\n }\n console.log('');\n }\n\n // If --docs is passed, auto-include 'docs' in modules\n if (docsPath && !modules.includes('docs')) {\n modules.push('docs');\n }\n\n // Auto-generate config.json if it doesn't exist yet\n if (!scan.config.exists && !skipPrompt) {\n await saveConfig(scan.repoPath, modules);\n }\n\n\n console.log(c.bold(`\\n━━━ Indexing: ${modules.join(', ')} ━━━`));\n\n const brain = await createBrain(repoPath);\n await brain.initialize();\n\n const config = await getConfig(repoPath);\n await registerConfigCollections(brain, repoPath, config);\n\n if (docsPath) {\n const absDocsPath = path.resolve(docsPath);\n const collName = path.basename(absDocsPath);\n try {\n const docsPlugin = findDocsPlugin(brain);\n await docsPlugin?.addCollection({\n name: collName,\n path: absDocsPath,\n pattern: '**/*.md',\n ignore: ['deprecated/**', 'node_modules/**'],\n });\n console.log(c.dim(` Registered docs collection: ${collName}`));\n } catch {\n console.log(c.yellow(` Warning: docs module not loaded, skipping --docs`));\n }\n }\n\n const result = await brain.index({\n modules,\n forceReindex: force,\n pluginOptions: { depth },\n onProgress: (stage, msg) => {\n process.stdout.write(`\\r ${c.cyan(stage.toUpperCase())} ${msg} `);\n },\n });\n\n console.log('\\n');\n for (const [name, value] of Object.entries(result)) {\n if (!value) continue;\n const v = value as Record<string, unknown>;\n if (typeof v.indexed === 'number') {\n const parts = [`${v.indexed} indexed`, `${v.skipped ?? 0} skipped`];\n if (typeof v.chunks === 'number') parts.push(`${v.chunks} chunks`);\n if (typeof v.removed === 'number' && v.removed > 0) parts.push(`${v.removed} removed`);\n console.log(` ${c.green(name)}: ${parts.join(', ')}`);\n } else {\n console.log(` ${c.green(name)}: done`);\n }\n }\n\n const stats = brain.stats();\n console.log(`\\n ${c.bold('Totals')}:`);\n for (const [name, s] of Object.entries(stats)) {\n if (!s || typeof s !== 'object') continue;\n const entries = Object.entries(s as Record<string, unknown>)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ');\n console.log(` ${name}: ${entries}`);\n }\n\n brain.close();\n\n // Auto-export MCP config to Antigravity if detected and not already configured\n await autoExportMcp(repoPath);\n}\n\n\nfunction printScanTree(scan: ScanResult, depth: number): void {\n console.clear();\n console.log(c.bold('\\n━━━ BrainBank Scan ━━━'));\n console.log(c.dim(` Repo: ${scan.repoPath}`));\n\n // Multi-repo detection\n if (scan.gitSubdirs.length > 0) {\n console.log(c.cyan(`\\n 🔀 Multi-repo — ${scan.gitSubdirs.length} git repos detected`));\n for (const sub of scan.gitSubdirs) {\n console.log(c.dim(` └── ${sub.name}`));\n }\n }\n\n // Dynamic module display\n for (const mod of scan.modules) {\n console.log('');\n if (mod.available) {\n const extra = mod.name === 'git' ? ` (depth: ${depth})` : '';\n console.log(` ${mod.icon} ${c.bold(capitalizeFirst(mod.name))} — ${mod.summary}${extra}`);\n if (mod.details) {\n for (const d of mod.details) {\n console.log(c.dim(` ${d}`));\n }\n }\n } else {\n console.log(` ${mod.icon} ${c.dim(`${capitalizeFirst(mod.name)} — ${mod.summary}`)}`);\n }\n }\n\n // Config ignore\n if (scan.config.ignore?.length) {\n console.log(c.dim(` Ignore: ${scan.config.ignore.join(', ')}`));\n }\n\n // Config & DB\n console.log('');\n if (scan.config.exists) {\n console.log(` ⚙️ ${c.dim('Config:')} .brainbank/config.json ${c.green('✓')}`);\n }\n if (scan.db?.exists) {\n const ago = scan.db.lastModified ? timeSince(scan.db.lastModified) : '';\n console.log(` 💾 ${c.dim('DB:')} ${scan.db.sizeMB} MB${ago ? `, last indexed ${ago}` : ''}`);\n } else {\n console.log(` 💾 ${c.dim('DB: new (first index)')}`);\n }\n console.log('');\n}\n\n\n/** Build the default list of available modules based on scan. */\nfunction buildDefaultModules(scan: ScanResult): string[] {\n return scan.modules.filter(m => m.available && m.checked).map(m => m.name);\n}\n\n/** Interactive checkbox prompt via @inquirer/prompts. */\nasync function promptModules(scan: ScanResult): Promise<string[]> {\n const { checkbox } = await import('@inquirer/prompts');\n console.log(c.dim(' ─────────────────────────────────────────\\n'));\n\n const choices = scan.modules.map((m: ScanModule) => ({\n name: `${capitalizeFirst(m.name).padEnd(6)} — ${m.summary}`,\n value: m.name,\n checked: m.checked && m.available,\n disabled: m.available ? undefined : m.disabled,\n }));\n\n return checkbox<string>({\n message: 'Select modules to index:\\n',\n choices,\n });\n}\n\n\nfunction timeSince(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\n/** Capitalize first letter. */\nfunction capitalizeFirst(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Generate .brainbank/config.json from the selected modules. */\nasync function saveConfig(repoPath: string, modules: string[]): Promise<void> {\n const { select, confirm } = await import('@inquirer/prompts');\n\n // Embedding provider selection\n const envEmbedding = process.env.BRAINBANK_EMBEDDING;\n const embedding = await select<string>({\n message: 'Embedding provider:',\n choices: [\n {\n name: 'perplexity-context — best accuracy (recommended)',\n value: 'perplexity-context',\n },\n {\n name: 'perplexity — fast, high quality',\n value: 'perplexity',\n },\n {\n name: 'openai — text-embedding-3-small',\n value: 'openai',\n },\n {\n name: 'local — offline, no API key needed',\n value: 'local',\n },\n ],\n default: envEmbedding ?? 'perplexity-context',\n });\n\n // Pruner selection\n const pruner = await select<string>({\n message: 'Noise pruner:',\n choices: [\n {\n name: 'haiku — AI-powered noise filter (recommended)',\n value: 'haiku',\n },\n {\n name: 'none — no pruning',\n value: 'none',\n },\n ],\n default: 'haiku',\n });\n\n const configDir = path.join(repoPath, '.brainbank');\n const configPath = path.join(configDir, 'config.json');\n\n const config: Record<string, unknown> = {\n plugins: modules,\n embedding,\n };\n\n if (pruner !== 'none') {\n config.pruner = pruner;\n }\n\n // Key management: detect available keys and offer to save\n const detectedKeys: Record<string, string> = {};\n const needsPerplexity = embedding.startsWith('perplexity');\n const needsAnthropic = pruner === 'haiku';\n const needsOpenai = embedding === 'openai';\n\n if (needsPerplexity && process.env.PERPLEXITY_API_KEY) {\n detectedKeys.perplexity = process.env.PERPLEXITY_API_KEY;\n }\n if (needsAnthropic && process.env.ANTHROPIC_API_KEY) {\n detectedKeys.anthropic = process.env.ANTHROPIC_API_KEY;\n }\n if (needsOpenai && process.env.OPENAI_API_KEY) {\n detectedKeys.openai = process.env.OPENAI_API_KEY;\n }\n\n if (Object.keys(detectedKeys).length > 0) {\n const keyNames = Object.keys(detectedKeys).join(', ');\n const saveKeys = await confirm({\n message: `Save API keys (${keyNames}) to config.json? (portable, no env vars needed)`,\n default: true,\n });\n if (saveKeys) {\n config.keys = detectedKeys;\n }\n }\n\n fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n');\n console.log(c.green(` ✓ Saved ${path.relative(process.cwd(), configPath)}`));\n}\n\n","/**\n * brainbank mcp:export [target] — Export MCP server config for AI IDEs.\n *\n * Generates the MCP server config block for brainbank and merges it into\n * the target IDE's config file. Currently supports: antigravity.\n *\n * Detects: node path, cli.js path, API keys from config or env vars.\n */\n\nimport type { ProjectConfig } from '@/cli/factory/config-loader.ts';\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { c, args, getFlag } from '@/cli/utils.ts';\nimport { getConfig } from '@/cli/factory/index.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/** Supported export targets and their config file paths. */\nconst TARGETS: Record<string, { configPath: string; label: string }> = {\n antigravity: {\n configPath: path.join(process.env.HOME ?? '~', '.gemini', 'antigravity', 'mcp_config.json'),\n label: 'Gemini Antigravity',\n },\n};\n\ninterface McpServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\ninterface McpConfig {\n mcpServers: Record<string, McpServerConfig>;\n}\n\n/**\n * Build the brainbank MCP server config block.\n * Resolves node binary, dist/cli.js path, and API keys.\n */\nfunction buildBrainbankMcpBlock(config: ProjectConfig | null, repoPath: string): McpServerConfig {\n const nodeBin = process.execPath;\n\n // Resolve dist/cli.js from the global install location (node_prefix/lib/node_modules/brainbank/dist/cli.js)\n const globalCliJs = path.join(path.dirname(nodeBin), '..', 'lib', 'node_modules', 'brainbank', 'dist', 'cli.js');\n // Fallback: relative to this file (dev / npm link)\n const localCliJs = path.resolve(__dirname, '..', '..', 'dist', 'cli.js');\n const resolvedCliJs = fs.existsSync(globalCliJs) ? globalCliJs : localCliJs;\n\n const env: Record<string, string> = {};\n\n // Resolve API keys: config.keys > env vars\n const keys = config?.keys;\n const perplexityKey = keys?.perplexity ?? process.env.PERPLEXITY_API_KEY;\n const anthropicKey = keys?.anthropic ?? process.env.ANTHROPIC_API_KEY;\n const openaiKey = keys?.openai ?? process.env.OPENAI_API_KEY;\n\n if (perplexityKey) env.PERPLEXITY_API_KEY = perplexityKey;\n if (anthropicKey) env.ANTHROPIC_API_KEY = anthropicKey;\n if (openaiKey) env.OPENAI_API_KEY = openaiKey;\n\n // Inject repo path so the MCP server knows where the index lives\n env.BRAINBANK_REPO = path.resolve(repoPath);\n\n const block: McpServerConfig = {\n command: nodeBin,\n args: ['--disable-warning=ExperimentalWarning', resolvedCliJs, 'mcp'],\n };\n\n if (Object.keys(env).length > 0) {\n block.env = env;\n }\n\n return block;\n}\n\n/**\n * Load existing MCP config, merge brainbank entry, and write back.\n * Preserves all other server entries.\n */\nfunction mergeAndWrite(targetPath: string, block: McpServerConfig): { created: boolean } {\n let existing: McpConfig = { mcpServers: {} };\n const created = !fs.existsSync(targetPath);\n\n if (!created) {\n try {\n const raw = fs.readFileSync(targetPath, 'utf-8');\n existing = JSON.parse(raw) as McpConfig;\n if (!existing.mcpServers) existing.mcpServers = {};\n } catch {\n // Corrupt or empty file — start fresh\n existing = { mcpServers: {} };\n }\n }\n\n existing.mcpServers.brainbank = block;\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, JSON.stringify(existing, null, 2) + '\\n');\n\n return { created };\n}\n\n/** Check if an MCP config already has a brainbank entry. */\nexport function hasBrainbankMcpEntry(targetPath: string): boolean {\n if (!fs.existsSync(targetPath)) return false;\n try {\n const raw = fs.readFileSync(targetPath, 'utf-8');\n const config = JSON.parse(raw) as McpConfig;\n return !!config.mcpServers?.brainbank;\n } catch {\n return false;\n }\n}\n\n/** Auto-export: called after index when Antigravity is detected. */\nexport async function autoExportMcp(repoPath: string): Promise<void> {\n const target = TARGETS.antigravity;\n if (!target) return;\n\n // Only auto-export if Antigravity dir exists\n const antigravityDir = path.dirname(target.configPath);\n if (!fs.existsSync(antigravityDir)) return;\n\n // Only auto-export if brainbank isn't already configured\n if (hasBrainbankMcpEntry(target.configPath)) return;\n\n const config = await getConfig(repoPath);\n const block = buildBrainbankMcpBlock(config, repoPath);\n mergeAndWrite(target.configPath, block);\n console.log(` ${c.green('✓')} Exported MCP config to ${c.dim(path.relative(process.env.HOME ?? '', target.configPath))}`);\n}\n\n// ── GEMINI.md BrainBank Section ──────────────────────────────\n\nconst BRAINBANK_SECTION_MARKER = '<!-- brainbank:start -->';\nconst BRAINBANK_SECTION_END = '<!-- brainbank:end -->';\n\n/** Global GEMINI.md path — ~/.gemini/GEMINI.md (shared across all projects). */\nconst GLOBAL_GEMINI = path.join(process.env.HOME ?? '~', '.gemini', 'GEMINI.md');\n\nfunction buildGeminiSection(): string {\n return `${BRAINBANK_SECTION_MARKER}\n\n## BrainBank — Code Intelligence\n\nWhen \\`brainbank_context\\` and \\`brainbank_files\\` MCP tools are available, **always use them instead of \\`grep_search\\` or \\`list_dir\\`**.\n\n**\\`brainbank_context\\`** — semantic search. \\`repo\\` is **required** (the project root where \\`brainbank index\\` was run). Use \\`path:\\` to scope within it, \\`compact: false\\`, \\`sources: { code: 25, docs: 0, git: 0 }\\`.\n\n**\\`brainbank_files\\`** — read full indexed files (\\`lines: true\\` always). Only works with files tracked by the index — for \\`.env\\`, \\`docker-compose.yml\\`, etc. use \\`view_file\\`.\n\n**Sources rule:** Default to code-only (\\`docs: 0\\`). Only add \\`docs\\` when the user explicitly asks about documentation. Never mix code and docs in the same query — fire separate queries.\n\n### Output handling (critical)\n\nBrainBank may return results **inline** or save them to an **output file**:\n\n- **Inline:** read and proceed normally.\n- **File result** (saved to \\`output.txt\\`): show the path as a clickable link, ask user to paste, then **STOP and WAIT**:\n\n 📋 Output: [output.txt](file:///path/to/output.txt) — _\"Could you paste the context output here?\"_\n\n Do **NOT** read the file yourself. Wait for the paste before proceeding.\n\n${BRAINBANK_SECTION_END}\n`;\n}\n\n/** Check if GEMINI.md already has the brainbank section. */\nfunction hasGeminiSection(geminiPath: string): boolean {\n if (!fs.existsSync(geminiPath)) return false;\n const content = fs.readFileSync(geminiPath, 'utf-8');\n return content.includes(BRAINBANK_SECTION_MARKER);\n}\n\n/** Append BrainBank section to GEMINI.md (creates if doesn't exist). */\nfunction appendGeminiSection(geminiPath: string): void {\n const section = buildGeminiSection();\n if (fs.existsSync(geminiPath)) {\n fs.appendFileSync(geminiPath, section);\n } else {\n fs.writeFileSync(geminiPath, `# GEMINI.md\\n${section}`);\n }\n}\n\n/** Replace BrainBank section between markers in GEMINI.md. */\nfunction replaceGeminiSection(geminiPath: string): void {\n const content = fs.readFileSync(geminiPath, 'utf-8');\n const startIdx = content.indexOf(BRAINBANK_SECTION_MARKER);\n const endIdx = content.indexOf(BRAINBANK_SECTION_END);\n if (startIdx === -1 || endIdx === -1) return;\n\n const before = content.slice(0, startIdx);\n const after = content.slice(endIdx + BRAINBANK_SECTION_END.length);\n const section = buildGeminiSection();\n fs.writeFileSync(geminiPath, before + section + after);\n}\n\n/** CLI command: brainbank mcp:export [target] */\nexport async function cmdMcpExport(): Promise<void> {\n const targetName = args[1] || getFlag('target') || 'antigravity';\n const repoPath = getFlag('repo') || '.';\n const { confirm } = await import('@inquirer/prompts');\n\n const target = TARGETS[targetName];\n if (!target) {\n console.error(c.red(`Unknown export target: ${targetName}`));\n console.error(c.dim(` Available: ${Object.keys(TARGETS).join(', ')}`));\n process.exit(1);\n }\n\n const config = await getConfig(repoPath);\n const block = buildBrainbankMcpBlock(config, repoPath);\n\n console.log(c.bold(`\\n━━━ MCP Export: ${target.label} ━━━\\n`));\n\n // ── MCP Config ────────────────────────────────────────────\n const mcpExists = hasBrainbankMcpEntry(target.configPath);\n let writeMcp = true;\n\n if (mcpExists) {\n console.log(` ${c.yellow('●')} MCP config already has brainbank entry`);\n const cliPath = block.args.find(a => !a.startsWith('--')) ?? block.args[0];\n console.log(` ${c.dim(' New:')} ${block.command} ${cliPath}`);\n const envKeys = block.env ? Object.keys(block.env) : [];\n if (envKeys.length > 0) console.log(` ${c.dim(' Keys:')} ${envKeys.join(', ')}`);\n writeMcp = await confirm({ message: 'Override existing brainbank MCP entry?', default: true });\n }\n\n if (writeMcp) {\n const { created } = mergeAndWrite(target.configPath, block);\n console.log(` ${c.green('✓')} ${created ? 'Created' : 'Updated'} ${c.dim(target.configPath)}`);\n } else {\n console.log(` ${c.dim('MCP config — skipped')}`);\n }\n\n // ── Global GEMINI.md (~/.gemini/GEMINI.md) ────────────────\n const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);\n\n if (geminiHasSection) {\n console.log(` ${c.yellow('●')} ~/.gemini/GEMINI.md already has BrainBank section`);\n const override = await confirm({ message: 'Override existing BrainBank section?', default: false });\n if (override) {\n replaceGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);\n } else {\n console.log(` ${c.dim('GEMINI.md — skipped')}`);\n }\n } else {\n const addGemini = await confirm({\n message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',\n default: true,\n });\n if (addGemini) {\n appendGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);\n }\n }\n\n console.log(`\\n ${c.dim('Restart your IDE to apply changes.')}\\n`);\n}\n","/**\n * brainbank scan — Lightweight repo scanner for the interactive index flow.\n *\n * Scans the filesystem WITHOUT initializing BrainBank. Returns a ScanResult\n * describing what's available to index via dynamic ScanModule descriptors.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { SUPPORTED_EXTENSIONS, isIgnoredDir, isIgnoredFile } from '@/lib/languages.ts';\n\n\n/** A single scannable module (plugin). */\nexport interface ScanModule {\n /** Plugin name (e.g. 'code', 'git', 'docs'). */\n name: string;\n /** Whether there's content available to index. */\n available: boolean;\n /** Human-readable summary (e.g. '1243 files (5 languages)'). */\n summary: string;\n /** Emoji icon for display. */\n icon: string;\n /** Whether checked by default in the prompt. */\n checked: boolean;\n /** Reason this module is disabled (shown in prompt). */\n disabled?: string;\n /** Detail lines for the scan tree (e.g. per-language breakdown). */\n details?: string[];\n}\n\nexport interface ScanResult {\n repoPath: string;\n modules: ScanModule[];\n config: { exists: boolean; ignore?: string[]; plugins?: string[] };\n db: { exists: boolean; sizeMB: number; lastModified?: Date } | null;\n gitSubdirs: { name: string }[];\n}\n\n\n/** Scan a repo path and return what's available to index. */\nexport function scanRepo(repoPath: string): ScanResult {\n const resolved = path.resolve(repoPath);\n const gitSubdirs = scanGitSubdirs(resolved);\n\n return {\n repoPath: resolved,\n modules: scanModules(resolved, gitSubdirs),\n config: scanConfig(resolved),\n db: scanDb(resolved),\n gitSubdirs,\n };\n}\n\n/** Produce ScanModule descriptors for known plugin types. */\nfunction scanModules(repoPath: string, gitSubdirs: { name: string }[]): ScanModule[] {\n return [\n scanCodeModule(repoPath),\n scanGitModule(repoPath, gitSubdirs),\n scanDocsModule(repoPath),\n ];\n}\n\n\n/** Scan for indexable code files. */\nfunction scanCodeModule(repoPath: string): ScanModule {\n const byLanguage = new Map<string, number>();\n let total = 0;\n\n function walk(dir: string): void {\n let entries: fs.Dirent[];\n try { entries = fs.readdirSync(dir, { withFileTypes: true }); }\n catch { return; }\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const isDir = entry.isDirectory() || (entry.isSymbolicLink() && (() => { try { return fs.statSync(fullPath).isDirectory(); } catch { return false; } })());\n if (isDir) {\n if (isIgnoredDir(entry.name)) continue;\n walk(fullPath);\n } else if (entry.isFile()) {\n if (isIgnoredFile(entry.name)) continue;\n const ext = path.extname(entry.name).toLowerCase();\n const lang = SUPPORTED_EXTENSIONS[ext];\n if (!lang) continue;\n byLanguage.set(lang, (byLanguage.get(lang) ?? 0) + 1);\n total++;\n }\n }\n }\n\n walk(repoPath);\n\n if (total === 0) {\n return { name: 'code', available: false, summary: 'no supported source files found', icon: '📁', checked: false, disabled: 'nothing to index' };\n }\n\n const langCount = byLanguage.size;\n const sorted = [...byLanguage.entries()].sort((a, b) => b[1] - a[1]);\n const maxShow = 7;\n const shown = sorted.slice(0, maxShow);\n const remaining = sorted.length - maxShow;\n\n const details: string[] = [];\n for (let i = 0; i < shown.length; i++) {\n const [lang, count] = shown[i];\n const isLast = i === shown.length - 1 && remaining <= 0;\n const prefix = isLast ? '└──' : '├──';\n details.push(`${prefix} ${lang.padEnd(14)} ${count} files`);\n }\n if (remaining > 0) {\n details.push(`└── ...and ${remaining} more`);\n }\n\n return {\n name: 'code',\n available: true,\n summary: `${total} files (${langCount} language${langCount > 1 ? 's' : ''})`,\n icon: '📁',\n checked: true,\n details,\n };\n}\n\n/** Scan for git history. */\nfunction scanGitModule(repoPath: string, gitSubdirs: { name: string }[]): ScanModule {\n const stats = scanGitStats(repoPath, gitSubdirs);\n\n if (!stats) {\n return { name: 'git', available: false, summary: 'no .git directory found', icon: '📜', checked: false, disabled: 'not a git repo' };\n }\n\n const details: string[] = [];\n if (stats.lastMessage) {\n details.push(`Last: ${stats.lastMessage} (${stats.lastDate})`);\n }\n\n return {\n name: 'git',\n available: true,\n summary: `${stats.commitCount.toLocaleString()} commits`,\n icon: '📜',\n checked: true,\n details,\n };\n}\n\n/** Scan for document collections. */\nfunction scanDocsModule(repoPath: string): ScanModule {\n const collections = scanDocsCollections(repoPath);\n\n if (collections.length === 0) {\n return { name: 'docs', available: false, summary: 'no documents found', icon: '📄', checked: false, disabled: 'no .md/.mdx files' };\n }\n\n const totalFiles = collections.reduce((s, d) => s + d.fileCount, 0);\n const details = collections.map((d, i) => {\n const isLast = i === collections.length - 1;\n const prefix = isLast ? '└──' : '├──';\n return `${prefix} ${d.name.padEnd(10)} → ${d.path} (${d.fileCount} files)`;\n });\n\n return {\n name: 'docs',\n available: true,\n summary: `${collections.length} collection${collections.length > 1 ? 's' : ''} (${totalFiles} files)`,\n icon: '📄',\n checked: true,\n details,\n };\n}\n\n\n/** Get git stats. Supports single repo and multi-repo aggregation. */\nfunction scanGitStats(repoPath: string, gitSubdirs: { name: string }[]): { commitCount: number; lastMessage: string; lastDate: string } | null {\n if (fs.existsSync(path.join(repoPath, '.git'))) {\n return gitStats(repoPath);\n }\n\n if (gitSubdirs.length === 0) return null;\n\n let totalCommits = 0;\n let latestMessage = '';\n let latestDate = '';\n\n for (const sub of gitSubdirs) {\n const stats = gitStats(path.join(repoPath, sub.name));\n if (stats) {\n totalCommits += stats.commitCount;\n if (!latestMessage) {\n latestMessage = stats.lastMessage;\n latestDate = stats.lastDate;\n }\n }\n }\n\n return totalCommits > 0\n ? { commitCount: totalCommits, lastMessage: latestMessage, lastDate: latestDate }\n : null;\n}\n\n/** Get git stats for a single directory. */\nfunction gitStats(dir: string): { commitCount: number; lastMessage: string; lastDate: string } | null {\n try {\n const count = parseInt(execSync('git rev-list --count HEAD', { cwd: dir, encoding: 'utf-8' }).trim(), 10);\n const log = execSync('git log -1 --format=\"%s|%ar\"', { cwd: dir, encoding: 'utf-8' }).trim();\n const [lastMessage, lastDate] = log.split('|');\n return { commitCount: count, lastMessage: lastMessage ?? '', lastDate: lastDate ?? '' };\n } catch {\n return null;\n }\n}\n\n/** Scan for document collections (config + auto-detect). */\nfunction scanDocsCollections(repoPath: string): { name: string; path: string; fileCount: number }[] {\n const results: { name: string; path: string; fileCount: number }[] = [];\n const seen = new Set<string>();\n\n // 1. Read explicit collections from config.json\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n try {\n if (fs.existsSync(configPath)) {\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const docsCfg = config?.docs as Record<string, unknown> | undefined;\n const collections = docsCfg?.collections as { name: string; path: string }[] | undefined;\n if (collections) {\n for (const coll of collections) {\n const absPath = path.resolve(repoPath, coll.path);\n results.push({ name: coll.name, path: coll.path, fileCount: countDocs(absPath) });\n seen.add(absPath);\n }\n }\n }\n } catch {}\n\n // 2. Auto-detect .md/.mdx in the repo root and top-level dirs\n const rootDocs = countDocsShallow(repoPath);\n if (rootDocs > 0) {\n results.push({ name: '(root)', path: '.', fileCount: rootDocs });\n }\n\n try {\n for (const entry of fs.readdirSync(repoPath, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n if (isIgnoredDir(entry.name)) continue;\n if (entry.name.startsWith('.')) continue;\n\n const dirPath = path.join(repoPath, entry.name);\n if (seen.has(dirPath)) continue;\n\n const count = countDocs(dirPath);\n if (count > 0) {\n results.push({ name: entry.name, path: `./${entry.name}`, fileCount: count });\n }\n }\n } catch {}\n\n return results;\n}\n\n/** Count .md/.mdx files recursively in a directory. */\nfunction countDocs(dir: string): number {\n let count = 0;\n try {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n const ePath = path.join(dir, e.name);\n const isDir = e.isDirectory() || (e.isSymbolicLink() && (() => { try { return fs.statSync(ePath).isDirectory(); } catch { return false; } })());\n if (isDir) {\n if (isIgnoredDir(e.name)) continue;\n count += countDocs(ePath);\n } else if ((e.isFile() || e.isSymbolicLink()) && /\\.mdx?$/i.test(e.name)) {\n count++;\n }\n }\n } catch {}\n return count;\n}\n\n/** Count .md/.mdx files in a directory (non-recursive, root level only). */\nfunction countDocsShallow(dir: string): number {\n let count = 0;\n try {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n if (e.isFile() && /\\.mdx?$/i.test(e.name)) count++;\n }\n } catch {}\n return count;\n}\n\n/** Check if config.json exists and read key fields. */\nfunction scanConfig(repoPath: string): ScanResult['config'] {\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n if (!fs.existsSync(configPath)) return { exists: false };\n\n try {\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const codeCfg = config?.code as Record<string, unknown> | undefined;\n return {\n exists: true,\n ignore: codeCfg?.ignore as string[] | undefined,\n plugins: config?.plugins as string[] | undefined,\n };\n } catch {\n return { exists: false };\n }\n}\n\n/** Check DB existence and size. */\nfunction scanDb(repoPath: string): ScanResult['db'] {\n const dbPath = path.join(repoPath, '.brainbank', 'data', 'brainbank.db');\n if (!fs.existsSync(dbPath)) return { exists: false, sizeMB: 0 };\n\n try {\n const stat = fs.statSync(dbPath);\n return {\n exists: true,\n sizeMB: Math.round(stat.size / 1024 / 1024 * 10) / 10,\n lastModified: stat.mtime,\n };\n } catch {\n return { exists: false, sizeMB: 0 };\n }\n}\n\n/** Detect subdirectories with their own .git (mono-repo). Respects `repos` whitelist from config. */\nfunction scanGitSubdirs(repoPath: string): ScanResult['gitSubdirs'] {\n if (fs.existsSync(path.join(repoPath, '.git'))) return [];\n\n try {\n let subdirs = fs.readdirSync(repoPath, { withFileTypes: true })\n .filter(e => {\n if (e.name.startsWith('.')) return false;\n const isDir = e.isDirectory() || (e.isSymbolicLink() && (() => { try { return fs.statSync(path.join(repoPath, e.name)).isDirectory(); } catch { return false; } })());\n return isDir;\n })\n .filter(e => fs.existsSync(path.join(repoPath, e.name, '.git')))\n .map(e => ({ name: e.name }));\n\n // Apply repos whitelist from config if present\n const configRepos = readReposFromConfig(repoPath);\n if (configRepos) {\n subdirs = subdirs.filter(s => configRepos.includes(s.name));\n }\n\n return subdirs;\n } catch {\n return [];\n }\n}\n\n/** Read the `repos` whitelist from .brainbank/config.json. Returns null if not set. */\nfunction readReposFromConfig(repoPath: string): string[] | null {\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n try {\n if (!fs.existsSync(configPath)) return null;\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const repos = config.repos;\n if (Array.isArray(repos) && repos.every(r => typeof r === 'string')) {\n return repos as string[];\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * brainbank collection add|list|remove — Document collection management\n */\n\nimport { c, args, getFlag, stripFlags, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdCollection(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n if (sub === 'add') {\n const path = pos[2];\n const name = getFlag('name');\n const pattern = getFlag('pattern') ?? '**/*.md';\n const context = getFlag('context');\n const ignoreRaw = getFlag('ignore');\n\n if (!path || !name) {\n console.log(c.red('Usage: brainbank collection add <path> --name <name> [--pattern \"**/*.md\"] [--ignore \"glob\"] [--context \"description\"]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded. Install @brainbank/docs.')); process.exit(1); }\n await docsPlugin.addCollection({\n name,\n path,\n pattern,\n ignore: ignoreRaw ? ignoreRaw.split(',') : [],\n context: context ?? undefined,\n });\n console.log(c.green(`✓ Collection '${name}' added: ${path} (${pattern})`));\n if (context) console.log(c.dim(` Context: ${context}`));\n brain.close();\n return;\n }\n\n if (sub === 'list') {\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.yellow(' Docs plugin not loaded.')); brain.close(); return; }\n const collections = docsPlugin.listCollections();\n if (collections.length === 0) {\n console.log(c.yellow(' No collections registered.'));\n } else {\n console.log(c.bold('\\n━━━ Collections ━━━\\n'));\n for (const col of collections) {\n console.log(` ${c.cyan(col.name)} ${c.dim('→')} ${col.path}`);\n console.log(` Pattern: ${col.pattern ?? '**/*.md'}`);\n if (col.context) console.log(` Context: ${c.dim(col.context)}`);\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'remove') {\n const name = pos[2];\n if (!name) {\n console.log(c.red('Usage: brainbank collection remove <name>'));\n process.exit(1);\n }\n const brain = await createBrain();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded.')); process.exit(1); }\n await docsPlugin.removeCollection(name);\n console.log(c.green(`✓ Collection '${name}' removed.`));\n brain.close();\n return;\n }\n\n console.log(c.red('Usage: brainbank collection <add|list|remove>'));\n process.exit(1);\n}\n","/**\n * brainbank kv add|search|list|trim|clear — Dynamic KV collection management\n */\n\nimport { c, args, getFlag, stripFlags } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdKv(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n if (sub === 'add') {\n const collName = pos[2];\n const content = pos.slice(3).join(' ');\n const metaRaw = getFlag('meta');\n\n if (!collName || !content) {\n console.log(c.red(\"Usage: brainbank kv add <collection> <content> [--meta '{\\\"key\\\":\\\"val\\\"}']\"));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const meta = metaRaw ? JSON.parse(metaRaw) : {};\n const id = await coll.add(content, meta);\n console.log(c.green(`✓ Added item #${id} to '${collName}'`));\n brain.close();\n return;\n }\n\n if (sub === 'search') {\n const collName = pos[2];\n const query = pos.slice(3).join(' ');\n const k = parseInt(getFlag('k') || '5', 10);\n const mode = (getFlag('mode') || 'hybrid') as 'hybrid' | 'vector' | 'keyword';\n\n if (!collName || !query) {\n console.log(c.red('Usage: brainbank kv search <collection> <query> [--k 5] [--mode hybrid|keyword|vector]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const results = await coll.search(query, { k, mode });\n\n if (results.length === 0) {\n console.log(c.yellow(' No results found.'));\n } else {\n console.log(c.bold(`\\n━━━ ${collName}: \"${query}\" ━━━\\n`));\n for (const r of results) {\n const score = Math.round((r.score ?? 0) * 100);\n console.log(` ${c.cyan(`[${score}%]`)} ${r.content}`);\n if (Object.keys(r.metadata).length > 0) {\n console.log(` ${c.dim(JSON.stringify(r.metadata))}`);\n }\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'list') {\n const collName = pos[2];\n const limit = parseInt(getFlag('limit') || '20', 10);\n\n if (!collName) {\n const brain = await createBrain();\n await brain.initialize();\n const names = brain.listCollectionNames();\n if (names.length === 0) {\n console.log(c.yellow(' No KV collections found.'));\n } else {\n console.log(c.bold('\\n━━━ KV Collections ━━━\\n'));\n for (const n of names) {\n const coll = brain.collection(n);\n console.log(` ${c.cyan(n)} — ${coll.count()} items`);\n }\n }\n brain.close();\n return;\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const items = coll.list({ limit });\n if (items.length === 0) {\n console.log(c.yellow(` Collection '${collName}' is empty.`));\n } else {\n console.log(c.bold(`\\n━━━ ${collName} (${coll.count()} items) ━━━\\n`));\n for (const item of items) {\n const age = Math.round((Date.now() / 1000 - item.createdAt) / 60);\n console.log(` #${item.id} ${c.dim(`(${age}m ago)`)} ${item.content.slice(0, 80)}`);\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'trim') {\n const collName = pos[2];\n const keep = parseInt(getFlag('keep') || '0', 10);\n\n if (!collName || keep <= 0) {\n console.log(c.red('Usage: brainbank kv trim <collection> --keep <n>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const result = await coll.trim({ keep });\n console.log(c.green(`✓ Trimmed ${result.removed} items from '${collName}' (kept ${keep})`));\n brain.close();\n return;\n }\n\n if (sub === 'clear') {\n const collName = pos[2];\n if (!collName) {\n console.log(c.red('Usage: brainbank kv clear <collection>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const before = coll.count();\n coll.clear();\n console.log(c.green(`✓ Cleared ${before} items from '${collName}'`));\n brain.close();\n return;\n }\n\n console.log(c.red('Usage: brainbank kv <add|search|list|trim|clear>'));\n process.exit(1);\n}\n\n","/**\n * brainbank docs — Index document collections\n * brainbank dsearch — Search documents only\n */\n\nimport { c, args, getFlag, stripFlags, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdDocs(): Promise<void> {\n const collection = getFlag('collection');\n const brain = await createBrain();\n\n console.log(c.bold('\\n━━━ BrainBank Docs Index ━━━\\n'));\n\n const opts: { collections?: string[]; onProgress?: (collection: string, file: string, current: number, total: number) => void } = {};\n if (collection) opts.collections = [collection];\n opts.onProgress = (col: string, file: string, cur: number, total: number) => {\n process.stdout.write(`\\r ${c.cyan(col)} [${cur}/${total}] ${file} `);\n };\n\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red(' Docs plugin not loaded. Install @brainbank/docs.')); process.exit(1); }\n\n const results = await docsPlugin.indexDocs(opts);\n\n console.log('\\n');\n for (const [name, stat] of Object.entries(results) as [string, { indexed: number; skipped: number; removed: number; chunks: number }][]) {\n const removedStr = stat.removed > 0 ? `, ${c.red(String(stat.removed) + ' removed')}` : '';\n console.log(` ${c.green(name)}: ${stat.indexed} indexed, ${stat.skipped} skipped${removedStr}, ${stat.chunks} chunks`);\n }\n\n brain.close();\n}\n\nexport async function cmdDocSearch(): Promise<void> {\n const query = stripFlags(args).slice(1).join(' ');\n if (!query) {\n console.log(c.red('Usage: brainbank dsearch <query>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n const collection = getFlag('collection');\n const k = parseInt(getFlag('k') || '8', 10);\n\n console.log(c.bold(`\\n━━━ BrainBank Doc Search: \"${query}\" ━━━\\n`));\n\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) {\n console.log(c.red('Docs plugin not loaded. Install @brainbank/docs.'));\n process.exit(1);\n }\n const results = await docsPlugin.search(query, { collection: collection ?? undefined, k });\n\n if (results.length === 0) {\n console.log(c.yellow(' No results found.'));\n brain.close();\n return;\n }\n\n for (const r of results) {\n const score = Math.round(r.score * 100);\n const ctx = r.context ? ` — ${c.dim(r.context)}` : '';\n console.log(`${c.magenta(`[DOC ${score}%]`)} ${c.bold(r.filePath!)} [${r.type === 'document' ? r.metadata.collection ?? '' : ''}]${ctx}`);\n const preview = r.content.split('\\n').slice(0, 4).join('\\n');\n console.log(c.dim(preview));\n console.log('');\n }\n\n brain.close();\n}\n","/**\n * brainbank search — Semantic search (vector)\n * brainbank hsearch — Hybrid search (vector + BM25)\n * brainbank ksearch — Keyword search (BM25)\n *\n * Source filtering:\n * --code 10 Max code results\n * --git 0 Skip git results\n * --docs 5 Max document results\n * --notes 10 Custom plugin results\n * --slack_messages 5 Custom collection results\n *\n * Any --<name> <number> flag is treated as a source filter.\n */\n\nimport { c, args, stripFlags, printResults } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\n/**\n * Parse dynamic source flags: each `--<name> <number>` becomes `{ name: number }`.\n *\n * Known non-source flags (--repo, --depth, etc.) are excluded.\n * Returns sources map + the query string (positional args).\n */\nfunction parseSourceFlags(): { sources: Record<string, number>; query: string } {\n const NON_SOURCE_FLAGS = new Set([\n 'repo', 'depth', 'collection', 'pattern', 'context', 'name',\n 'keep', 'reranker', 'pruner', 'only', 'docs-path', 'mode', 'limit',\n 'ignore', 'meta', 'k', 'yes', 'y', 'force', 'verbose',\n ]);\n\n const sources: Record<string, number> = {};\n const positional: string[] = [];\n\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n const name = args[i].slice(2);\n\n // Skip boolean flags\n if (name === 'yes' || name === 'force' || name === 'verbose') continue;\n\n // If next arg is a number and flag is not a known non-source flag\n const next = args[i + 1];\n if (next !== undefined && /^\\d+$/.test(next) && !NON_SOURCE_FLAGS.has(name)) {\n sources[name] = parseInt(next, 10);\n i++; // skip the value\n continue;\n }\n\n // Known value flag — skip its value\n if (NON_SOURCE_FLAGS.has(name) && next !== undefined && !next.startsWith('--')) {\n i++;\n }\n continue;\n }\n positional.push(args[i]);\n }\n\n const query = positional.slice(1).join(' '); // skip command name\n return { sources, query };\n}\n\n/** Print active source filters. */\nfunction printFilterInfo(sources: Record<string, number>): void {\n const entries = Object.entries(sources);\n if (entries.length === 0) return;\n const parts = entries.map(([k, v]) => `${k}=${v}`);\n console.log(c.dim(` Sources: ${parts.join(', ')}`));\n}\n\n/** Build search options from sources map. */\nfunction buildSearchOptions(sources: Record<string, number>): { sources: Record<string, number>; source: 'cli' } {\n return Object.keys(sources).length > 0 ? { sources, source: 'cli' } : { sources: {}, source: 'cli' };\n}\n\nexport async function cmdSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank search <query> [--code <n>] [--git <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n console.log(c.bold(`\\n━━━ BrainBank Search: \"${query}\" ━━━\\n`));\n printFilterInfo(sources);\n\n const opts = buildSearchOptions(sources);\n const results = await brain.search(query, opts);\n printResults(results);\n brain.close();\n}\n\nexport async function cmdHybridSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank hsearch <query> [--code <n>] [--git <n>] [--docs <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n console.log(c.bold(`\\n━━━ BrainBank Hybrid Search: \"${query}\" ━━━`));\n console.log(c.dim(` Mode: vector + BM25 → Reciprocal Rank Fusion`));\n printFilterInfo(sources);\n console.log('');\n\n const opts = buildSearchOptions(sources);\n const results = await brain.hybridSearch(query, opts);\n printResults(results);\n brain.close();\n}\n\nexport async function cmdKeywordSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank ksearch <query> [--code <n>] [--git <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n console.log(c.bold(`\\n━━━ BrainBank Keyword Search: \"${query}\" ━━━`));\n console.log(c.dim(` Mode: BM25 full-text (instant)`));\n printFilterInfo(sources);\n console.log('');\n\n const opts = buildSearchOptions(sources);\n const results = await brain.searchBM25(query, opts);\n printResults(results);\n brain.close();\n}\n","/**\n * ServerClient — Lightweight HTTP client for the BrainBank daemon.\n *\n * Used by CLI commands to delegate to a running HTTP server\n * instead of loading models locally. Falls back gracefully\n * (returns null) if the server is unreachable.\n */\n\nimport * as http from 'node:http';\n\nimport { isServerRunning } from '@/services/daemon.ts';\n\ninterface ContextOptions {\n task: string;\n repo?: string;\n sources?: Record<string, number>;\n pathPrefix?: string;\n affectedFiles?: string[];\n}\n\n/**\n * Try to get context from the running HTTP server.\n * Returns the context string if successful, null if server is unreachable.\n */\nexport async function tryServerContext(options: ContextOptions): Promise<string | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const body = JSON.stringify({\n task: options.task,\n repo: options.repo,\n sources: options.sources,\n pathPrefix: options.pathPrefix,\n affectedFiles: options.affectedFiles,\n });\n\n const response = await httpPost(info.port, '/context', body);\n const data = JSON.parse(response) as { context?: string; error?: string };\n\n if (data.error) return null;\n return data.context ?? null;\n } catch {\n // Server unreachable or error — fall back to local\n return null;\n }\n}\n\n/**\n * Try to trigger indexing on the running HTTP server.\n * Returns the result if successful, null if server is unreachable.\n */\nexport async function tryServerIndex(repo?: string, forceReindex?: boolean): Promise<Record<string, unknown> | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const body = JSON.stringify({ repo, forceReindex });\n const response = await httpPost(info.port, '/index', body);\n const data = JSON.parse(response) as { result?: Record<string, unknown>; error?: string };\n\n if (data.error) return null;\n return data.result ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check server health. Returns health info or null.\n */\nexport async function serverHealth(): Promise<{\n ok: boolean;\n pid: number;\n port: number;\n uptime: number;\n workspaces: number;\n} | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const response = await httpGet(info.port, '/health');\n return JSON.parse(response) as { ok: boolean; pid: number; port: number; uptime: number; workspaces: number };\n } catch {\n return null;\n }\n}\n\n// ── HTTP helpers ────────────────────────────────────\n\nfunction httpPost(port: number, path: string, body: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const req = http.request({\n hostname: '127.0.0.1',\n port,\n path,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n timeout: 120_000, // 2 minutes — context queries can be slow on first load\n }, (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n });\n\n req.on('error', reject);\n req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });\n req.write(body);\n req.end();\n });\n}\n\nfunction httpGet(port: number, path: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const req = http.request({\n hostname: '127.0.0.1',\n port,\n path,\n method: 'GET',\n timeout: 5_000,\n }, (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n });\n\n req.on('error', reject);\n req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });\n req.end();\n });\n}\n","/**\n * brainbank context <task> — Get formatted context for a task\n * brainbank context add <collection> <path> <description>\n * brainbank context list\n *\n * Source filtering (same as search commands):\n * --code 20 Max code results (default: 20)\n * --git 5 Max git results\n * --no-git Skip git results\n * --no-code Skip code results\n * --path <dir> Filter results to files under this path prefix\n * --ignore <paths> Exclude paths (comma-separated or repeated: --ignore a,b --ignore c)\n */\n\nimport { c, args, stripFlags, getFlag, getFlagAll, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\nimport { tryServerContext } from '@/cli/server-client.ts';\n\n/** Parse --code N, --git N, --no-git, --no-code flags into sources map. */\nfunction parseContextFlags(): Record<string, number> {\n const NON_SOURCE = new Set([\n 'repo', 'depth', 'collection', 'pattern', 'context', 'name',\n 'keep', 'reranker', 'pruner', 'only', 'docs-path', 'mode', 'limit',\n 'ignore', 'meta', 'k', 'yes', 'y', 'force', 'verbose', 'path',\n ]);\n const sources: Record<string, number> = {};\n for (let i = 0; i < args.length; i++) {\n if (!args[i].startsWith('--')) continue;\n const name = args[i].slice(2);\n // --no-git, --no-code → set to 0\n if (name.startsWith('no-')) {\n sources[name.slice(3)] = 0;\n continue;\n }\n // --code 20, --git 5\n const next = args[i + 1];\n if (next !== undefined && /^\\d+$/.test(next) && !NON_SOURCE.has(name)) {\n sources[name] = parseInt(next, 10);\n i++;\n }\n }\n return sources;\n}\n\nexport async function cmdContext(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n // brainbank context add <collection> <path> <description>\n if (sub === 'add') {\n const collection = pos[2];\n const path = pos[3];\n const desc = pos.slice(4).join(' ');\n\n if (!collection || !path || !desc) {\n console.log(c.red('Usage: brainbank context add <collection> <path> <description>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded.')); process.exit(1); }\n docsPlugin.addContext(collection, path, desc);\n console.log(c.green(`✓ Context added: ${collection}:${path} → \"${desc}\"`));\n brain.close();\n return;\n }\n\n // brainbank context list\n if (sub === 'list') {\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.yellow(' Docs plugin not loaded.')); brain.close(); return; }\n const contexts = docsPlugin.listContexts();\n if (contexts.length === 0) {\n console.log(c.yellow(' No contexts configured.'));\n } else {\n console.log(c.bold('\\n━━━ Contexts ━━━\\n'));\n for (const ctx of contexts) {\n console.log(` ${c.cyan(ctx.collection)}:${ctx.path} → ${c.dim(ctx.context)}`);\n }\n }\n brain.close();\n return;\n }\n\n // brainbank context <task> — get formatted context\n const task = stripFlags(args).slice(1).join(' ');\n if (!task) {\n console.log(c.red('Usage: brainbank context <task description>'));\n console.log(c.dim(' brainbank context add <collection> <path> <description>'));\n console.log(c.dim(' brainbank context list'));\n process.exit(1);\n }\n\n const sources = parseContextFlags();\n const pathPrefix = getFlag('path');\n const ignorePaths = getFlagAll('ignore');\n const repo = getFlag('repo');\n\n // Parse BrainBankQL field flags\n const fields = parseFieldFlags();\n\n // Try HTTP server delegation first\n const serverResult = await tryServerContext({\n task,\n repo: repo ?? process.cwd(),\n sources: Object.keys(sources).length > 0 ? sources : undefined,\n pathPrefix,\n });\n\n if (serverResult !== null) {\n console.log(serverResult);\n return;\n }\n\n // Fall back to local\n const brain = await createBrain();\n const context = await brain.getContext(task, {\n sources: Object.keys(sources).length > 0 ? sources : undefined,\n pathPrefix,\n ignorePaths: ignorePaths.length > 0 ? ignorePaths : undefined,\n source: 'cli',\n fields: Object.keys(fields).length > 0 ? fields : undefined,\n });\n console.log(context);\n brain.close();\n}\n\n/** Parse BrainBankQL field flags: --lines, --symbols, --compact, --no-callTree, --callTree.depth=N, etc. */\nfunction parseFieldFlags(): Record<string, unknown> {\n const FIELD_BOOLEANS = new Set(['lines', 'symbols', 'compact', 'expander']);\n const FIELD_NEGATABLE = new Set(['callTree', 'imports']);\n const fields: Record<string, unknown> = {};\n\n for (let i = 0; i < args.length; i++) {\n if (!args[i].startsWith('--')) continue;\n const raw = args[i].slice(2);\n\n // --no-callTree, --no-imports → set to false\n if (raw.startsWith('no-')) {\n const name = raw.slice(3);\n if (FIELD_NEGATABLE.has(name)) {\n fields[name] = false;\n }\n continue;\n }\n\n // --callTree.depth=4 → { depth: 4 }\n const dotIdx = raw.indexOf('.');\n if (dotIdx > 0) {\n const fieldName = raw.slice(0, dotIdx);\n const rest = raw.slice(dotIdx + 1);\n const eqIdx = rest.indexOf('=');\n if (eqIdx > 0) {\n const key = rest.slice(0, eqIdx);\n const val = parseInt(rest.slice(eqIdx + 1), 10);\n if (!isNaN(val)) {\n fields[fieldName] = { [key]: val };\n }\n }\n continue;\n }\n\n // --lines, --symbols, --compact, --expander → true\n if (FIELD_BOOLEANS.has(raw)) {\n fields[raw] = true;\n }\n }\n\n return fields;\n}\n","/**\n * brainbank files <path|glob> [...paths] [--lines]\n *\n * Fetch full file contents from the index.\n * Use after `brainbank context` to view complete files identified by search.\n */\n\nimport { c, args, getFlag } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdFiles(): Promise<void> {\n // Collect positional args (file patterns) — skip 'files' command itself\n const patterns: string[] = [];\n const showLines = args.includes('--lines');\n\n for (let i = 1; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n // Skip --lines and --repo <value>\n if (args[i] === '--repo') {\n i++; // skip value\n }\n continue;\n }\n patterns.push(args[i]);\n }\n\n if (patterns.length === 0) {\n console.log(c.red('Usage: brainbank files <path|glob> [...paths] [--lines]'));\n console.log(c.dim(' Exact: brainbank files src/auth/login.ts'));\n console.log(c.dim(' Directory: brainbank files src/graph/'));\n console.log(c.dim(' Glob: brainbank files \"src/**/*.service.ts\"'));\n console.log(c.dim(' Fuzzy: brainbank files plugin.ts'));\n console.log(c.dim(' Lines: brainbank files src/plugin.ts --lines'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const results = brain.resolveFiles(patterns);\n\n if (results.length === 0) {\n console.log(c.yellow('No matching files found in the index.'));\n console.log(c.dim('Run `brainbank index` first to index your codebase.'));\n brain.close();\n return;\n }\n\n // Format output\n for (const r of results) {\n const meta = r.metadata as Record<string, unknown>;\n const startLine = (meta.startLine as number) ?? 1;\n\n console.log(c.bold(`\\n── ${r.filePath} ──\\n`));\n\n if (showLines) {\n const codeLines = r.content.split('\\n');\n const pad = String(startLine + codeLines.length - 1).length;\n for (let i = 0; i < codeLines.length; i++) {\n const lineNum = c.dim(`${String(startLine + i).padStart(pad)}|`);\n console.log(`${lineNum} ${codeLines[i]}`);\n }\n } else {\n console.log(r.content);\n }\n }\n\n console.log(c.dim(`\\n${results.length} file(s) resolved.`));\n brain.close();\n}\n","/** brainbank stats — Show index statistics. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\n/** Convert camelCase/snake_case stat keys to human-readable labels. */\nfunction formatStatKey(key: string): string {\n return key\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase())\n .padEnd(16);\n}\n\nexport async function cmdStats(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n const s = brain.stats();\n\n console.log(c.bold('\\n━━━ BrainBank Stats ━━━\\n'));\n console.log(` ${c.cyan('Plugins')}: ${brain.plugins.join(', ')}\\n`);\n\n for (const [name, pluginStats] of Object.entries(s)) {\n if (!pluginStats) continue;\n console.log(` ${c.cyan(name)}`);\n for (const [key, value] of Object.entries(pluginStats)) {\n console.log(` ${formatStatKey(key)}${value}`);\n }\n console.log('');\n }\n\n const kvNames = brain.listCollectionNames();\n if (kvNames.length > 0) {\n console.log(` ${c.cyan('KV Collections')}`);\n for (const name of kvNames) {\n const coll = brain.collection(name);\n console.log(` ${name}: ${coll.count()} items`);\n }\n console.log('');\n }\n\n brain.close();\n}\n","/** brainbank reembed — Re-embed all vectors. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdReembed(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n console.log(c.bold('\\n━━━ BrainBank Re-embed ━━━\\n'));\n console.log(c.dim(' Regenerating vectors with current embedding provider...'));\n console.log(c.dim(' Text, FTS, and metadata remain unchanged.\\n'));\n\n const result = await brain.reembed({\n onProgress: (table: string, current: number, total: number) => {\n process.stdout.write(`\\r ${c.cyan(table.padEnd(8))} ${current}/${total}`);\n },\n });\n\n console.log('\\n');\n for (const [name, count] of Object.entries(result.counts)) {\n if (count > 0) {\n const label = name.charAt(0).toUpperCase() + name.slice(1);\n console.log(` ${c.green('✓')} ${label.padEnd(8)} ${count} vectors`);\n }\n }\n console.log(`\\n ${c.bold('Total')}: ${result.total} vectors regenerated\\n`);\n\n brain.close();\n}\n","/** brainbank watch — Watch for file changes. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\nimport { loadConfig } from '@/cli/factory/config-loader.ts';\n\nexport async function cmdWatch(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n // Read ignore patterns from config (code.ignore + top-level ignore)\n const config = await loadConfig(brain.config.repoPath);\n const codeIgnore = (config?.code as Record<string, unknown> | undefined)?.ignore as string[] ?? [];\n\n console.log(c.bold('\\n━━━ BrainBank Watch ━━━\\n'));\n console.log(c.dim(` Watching ${brain.config.repoPath} for changes...`));\n if (codeIgnore.length > 0) {\n console.log(c.dim(` Ignoring: ${codeIgnore.join(', ')}`));\n }\n console.log(c.dim(' Press Ctrl+C to stop.\\n'));\n\n const watcher = brain.watch({\n debounceMs: 2000,\n ignore: codeIgnore,\n onIndex: (sourceId: string, pluginName: string) => {\n const ts = new Date().toLocaleTimeString();\n console.log(` ${c.dim(ts)} ${c.green('✓')} ${c.cyan(pluginName)}: ${sourceId}`);\n },\n onError: (err: Error) => {\n console.error(` ${c.red('✗')} ${err.message}`);\n },\n });\n\n process.on('SIGINT', () => {\n console.log(c.dim('\\n Stopping watcher...'));\n watcher.close();\n brain.close();\n process.exit(0);\n });\n\n await new Promise(() => {});\n}\n\n","/** brainbank mcp — Start MCP server (stdio). Requires @brainbank/mcp. */\n\nimport { c } from '@/cli/utils.ts';\n\nexport async function cmdMcp(): Promise<void> {\n try {\n await import('@brainbank/mcp');\n } catch {\n console.error(c.red('Error: @brainbank/mcp is not installed.'));\n console.error(c.dim(' Install: npm i @brainbank/mcp'));\n process.exit(1);\n }\n}\n","/**\n * brainbank daemon — HTTP daemon for CLI delegation.\n *\n * brainbank daemon → Start foreground\n * brainbank daemon start → Start background (fork + PID file)\n * brainbank daemon stop → Stop background daemon\n * brainbank daemon restart → Stop + start\n */\n\nimport { c, args, getFlag, stripFlags } from '@/cli/utils.ts';\nimport { isServerRunning, removePid, DEFAULT_PORT } from '@/services/daemon.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdDaemon(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1]; // start | stop | undefined\n\n if (sub === 'stop') return stopDaemon();\n if (sub === 'restart') { stopDaemon(); return forkDaemon(); }\n if (sub === 'start') return forkDaemon();\n return startForeground();\n}\n\n// ── Foreground ──────────────────────────────────\n\nasync function startForeground(): Promise<void> {\n const port = parseInt(getFlag('port') ?? String(DEFAULT_PORT), 10);\n const { HttpServer } = await import('@/services/http-server.ts');\n\n const server = new HttpServer({\n port,\n factory: async (repoPath: string) => {\n const brain = await createBrain(repoPath);\n await brain.initialize();\n return brain;\n },\n onError: (repo, err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(c.red(` Pool error [${repo}]: ${msg}`));\n },\n onLog: (msg) => console.log(c.dim(` ${msg}`)),\n });\n\n console.log(c.bold('\\n━━━ BrainBank HTTP Daemon ━━━\\n'));\n\n await server.start();\n\n console.log(c.dim(` Port: ${port}`));\n console.log(c.dim(' Press Ctrl+C to stop.\\n'));\n\n const shutdown = () => {\n console.log(c.dim('\\n Shutting down...'));\n server.close();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await new Promise(() => {});\n}\n\n// ── Background ──────────────────────────────────\n\nasync function forkDaemon(): Promise<void> {\n const port = parseInt(getFlag('port') ?? String(DEFAULT_PORT), 10);\n const { fork } = await import('node:child_process');\n\n const existing = isServerRunning();\n if (existing) {\n console.log(c.yellow(` Daemon already running (PID ${existing.pid}, port ${existing.port})`));\n return;\n }\n\n const child = fork(process.argv[1], ['daemon', '--port', String(port)], {\n detached: true,\n stdio: 'ignore',\n });\n\n child.unref();\n\n console.log(c.green(` ✓ Daemon started (PID ${child.pid}, port ${port})`));\n console.log(c.dim(' Stop with: brainbank daemon stop'));\n}\n\nfunction stopDaemon(): void {\n const info = isServerRunning();\n if (!info) {\n console.log(c.yellow(' No daemon running.'));\n return;\n }\n\n try {\n process.kill(info.pid, 'SIGTERM');\n removePid();\n console.log(c.green(` ✓ Daemon stopped (PID ${info.pid})`));\n } catch {\n removePid();\n console.log(c.yellow(` PID ${info.pid} not found. Cleaned up stale PID file.`));\n }\n}\n","/**\n * Status Command — Show BrainBank server status.\n *\n * Usage: brainbank status\n */\n\nimport { c } from '@/cli/utils.ts';\nimport { serverHealth } from '@/cli/server-client.ts';\nimport { isServerRunning } from '@/services/daemon.ts';\n\nfunction formatUptime(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return remainMinutes > 0 ? `${hours}h ${remainMinutes}m` : `${hours}h`;\n}\n\nexport async function cmdStatus(): Promise<void> {\n const info = isServerRunning();\n\n if (!info) {\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.yellow('stopped')}\\n`);\n console.log(c.dim(' Start with: brainbank daemon'));\n console.log('');\n return;\n }\n\n // Try to get detailed health from the server\n const health = await serverHealth();\n\n if (health) {\n const uptime = formatUptime(health.uptime);\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.green('running')}`);\n console.log(` ${c.dim('PID:')} ${health.pid}`);\n console.log(` ${c.dim('Port:')} ${health.port}`);\n console.log(` ${c.dim('Uptime:')} ${uptime}`);\n console.log(` ${c.dim('Workspaces:')} ${health.workspaces}`);\n console.log('');\n } else {\n // PID file exists but server not responding\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.yellow('stale')} (PID ${info.pid} not responding)`);\n console.log(c.dim(' The PID file may be stale. Restart with: brainbank daemon'));\n console.log('');\n }\n}\n","/** brainbank help — Show CLI usage. */\n\nimport { c } from '@/cli/utils.ts';\n\nexport function showHelp(): void {\n console.log(c.bold('\\n━━━ BrainBank — Semantic Knowledge Bank ━━━\\n'));\n console.log(c.bold('Indexing:'));\n console.log(` ${c.cyan('index')} ${c.dim('(i)')} [path] Index code + git history`);\n console.log(` ${c.cyan('collection add')} <path> --name Add a document collection`);\n console.log(` ${c.cyan('collection list')} List collections`);\n console.log(` ${c.cyan('collection remove')} <name> Remove a collection`);\n console.log(` ${c.cyan('docs')} [--collection <name>] Index document collections`);\n console.log('');\n console.log(c.bold('Search:'));\n console.log(` ${c.cyan('search')} <query> Semantic search (vector)`);\n console.log(` ${c.cyan('hsearch')} <query> Hybrid search (${c.bold('best quality')})`);\n console.log(` ${c.cyan('ksearch')} <query> Keyword search (BM25, instant)`);\n console.log(` ${c.cyan('dsearch')} <query> Document search`);\n console.log(c.dim(' All search commands accept --<source> <n> to filter by source'));\n console.log('');\n console.log(c.bold('Context:'));\n console.log(` ${c.cyan('context')} <task> Get formatted context for a task`);\n console.log(` ${c.cyan('context add')} <col> <path> <desc> Add context metadata`);\n console.log(` ${c.cyan('context list')} List all context metadata`);\n console.log(` ${c.cyan('files')} <path|glob> [...] [--lines] View full indexed files directly`);\n console.log('');\n console.log(c.bold('KV Store:'));\n console.log(` ${c.cyan('kv add')} <coll> <content> Add item to a collection`);\n console.log(` ${c.cyan('kv search')} <coll> <query> Search a collection`);\n console.log(` ${c.cyan('kv list')} [coll] List collections or items`);\n console.log(` ${c.cyan('kv trim')} <coll> --keep <n> Keep only N most recent`);\n console.log(` ${c.cyan('kv clear')} <coll> Clear all items`);\n console.log('');\n console.log(c.bold('Utility:'));\n console.log(` ${c.cyan('stats')} Show index statistics`);\n console.log(` ${c.cyan('reembed')} Re-embed all vectors`);\n console.log(` ${c.cyan('watch')} Watch files, auto-re-index`);\n console.log(` ${c.cyan('mcp')} Start MCP server (stdio)`);\n console.log(` ${c.cyan('mcp:export')} [target] Export MCP config (antigravity)`);\n console.log(` ${c.cyan('daemon')} Start HTTP daemon (foreground)`);\n console.log(` ${c.cyan('daemon start')} Start HTTP daemon (background)`);\n console.log(` ${c.cyan('daemon stop')} Stop background daemon`);\n console.log(` ${c.cyan('daemon restart')} Restart background daemon`);\n console.log(` ${c.cyan('status')} Show daemon status`);\n console.log(` ${c.cyan('--version')} ${c.dim('(-v)')} Show version`);\n console.log('');\n console.log(c.bold('Options:'));\n console.log(` ${c.dim('--repo <path>')} Repository path (default: .)`);\n console.log(` ${c.dim('--force')} Force re-index all files`);\n console.log(` ${c.dim('--depth <n>')} Git history depth (default: 500)`);\n console.log(` ${c.dim('--collection <name>')} Filter by collection`);\n console.log(` ${c.dim('--pattern <glob>')} Collection glob (default: **/*.md)`);\n console.log(` ${c.dim('--context <desc>')} Context description`);\n console.log(` ${c.dim('--<source> <n>')} Source filter: max results from <source> (0 = skip)`);\n console.log(` ${c.dim('--path <dir>')} Filter context results to files under this path prefix`);\n console.log(` ${c.dim('--ignore <globs>')} Ignore glob patterns for code indexing (comma-separated)`);\n console.log(` ${c.dim('--yes / -y')} Skip interactive prompt (auto-select all available)`);\n console.log(` ${c.dim('--reranker <name>')} Reranker to use (qwen3)`);\n console.log(` ${c.dim('--port <n>')} HTTP daemon port (default: 8181)`);\n console.log('');\n console.log(c.bold('Examples:'));\n console.log(c.dim(' brainbank index .'));\n console.log(c.dim(' brainbank index . --ignore \"sdk/**,vendor/**\"'));\n console.log(c.dim(' brainbank kv add errors \"Fixed null pointer in api.ts\"'));\n console.log(c.dim(' brainbank kv search errors \"null pointer\"'));\n console.log(c.dim(' brainbank kv list'));\n console.log(c.dim(' brainbank hsearch \"authentication middleware\"'));\n console.log(c.dim(' brainbank hsearch \"auth\" --code 0 --git 10 # git only'));\n console.log(c.dim(' brainbank search \"handler\" --git 0 # code only'));\n console.log(c.dim(' brainbank hsearch \"api\" --docs 10 --code 0 --git 0 # docs only'));\n console.log(c.dim(' brainbank context \"auth flow\" | pbcopy # → clipboard'));\n console.log(c.dim(' brainbank daemon start # background HTTP'));\n console.log(c.dim(' brainbank mcp # MCP stdio'));\n console.log(c.dim(' brainbank mcp:export antigravity # export MCP config'));\n}\n","#!/usr/bin/env node\n\n/**\n * BrainBank — CLI Entry Point\n *\n * Dispatcher that routes commands to their handler modules.\n */\n\nimport { args, c } from './utils.ts';\nimport { cmdIndex } from './commands/index.ts';\nimport { cmdCollection } from './commands/collection.ts';\nimport { cmdKv } from './commands/kv.ts';\nimport { cmdDocs, cmdDocSearch } from './commands/docs.ts';\nimport { cmdSearch, cmdHybridSearch, cmdKeywordSearch } from './commands/search.ts';\nimport { cmdContext } from './commands/context.ts';\nimport { cmdFiles } from './commands/files.ts';\nimport { cmdStats } from './commands/stats.ts';\nimport { cmdReembed } from './commands/reembed.ts';\nimport { cmdWatch } from './commands/watch.ts';\nimport { cmdMcp } from './commands/mcp.ts';\nimport { cmdMcpExport } from './commands/mcp-export.ts';\nimport { cmdDaemon } from './commands/daemon.ts';\nimport { cmdStatus } from './commands/status.ts';\nimport { showHelp } from './commands/help.ts';\nimport { VERSION } from '@/constants.ts';\n\nconst command = args[0];\n\nasync function main(): Promise<void> {\n switch (command) {\n case '--version':\n case '-v':\n console.log(`brainbank v${VERSION}`);\n break;\n case 'i':\n case 'index': return cmdIndex();\n case 'collection': return cmdCollection();\n case 'kv': return cmdKv();\n case 'docs': return cmdDocs();\n case 'dsearch': return cmdDocSearch();\n case 'search': return cmdSearch();\n case 'hsearch': return cmdHybridSearch();\n case 'ksearch': return cmdKeywordSearch();\n case 'context': return cmdContext();\n case 'files': return cmdFiles();\n case 'stats': return cmdStats();\n case 'reembed': return cmdReembed();\n case 'watch': return cmdWatch();\n case 'mcp': return cmdMcp();\n case 'mcp:export': return cmdMcpExport();\n case 'serve': return cmdMcp(); // backward compat\n case 'daemon': return cmdDaemon();\n case 'status': return cmdStatus();\n case 'help':\n case '--help':\n case '-h':\n showHelp();\n break;\n default:\n if (command) console.log(c.red(`Unknown command: ${command}\\n`));\n showHelp();\n process.exit(command ? 1 : 0);\n }\n}\n\nmain().catch(err => {\n console.error(c.red(`Error: ${err.message}`));\n if (process.env.BRAINBANK_DEBUG) console.error(err.stack);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","fs","path","path","brain","coll","path","resolve","path","brain","c"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/index.ts","../src/cli/commands/mcp-export.ts","../src/cli/commands/scan.ts","../src/cli/commands/collection.ts","../src/cli/commands/kv.ts","../src/cli/commands/docs.ts","../src/cli/commands/search.ts","../src/cli/server-client.ts","../src/cli/commands/context.ts","../src/cli/commands/files.ts","../src/cli/commands/stats.ts","../src/cli/commands/reembed.ts","../src/cli/commands/watch.ts","../src/cli/commands/mcp.ts","../src/cli/commands/daemon.ts","../src/cli/commands/status.ts","../src/cli/commands/help.ts","../src/cli/index.ts"],"sourcesContent":["/**\n * brainbank index [path] — Interactive scan → select → index\n *\n * Scans the repo first, shows a summary tree, and prompts the user\n * with checkboxes to select which modules to index. Use --yes to skip.\n */\n\nimport type { ScanResult, ScanModule } from './scan.ts';\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { c, args, getFlag, hasFlag, stripFlags } from '@/cli/utils.ts';\nimport { createBrain, getConfig, registerConfigCollections } from '@/cli/factory/index.ts';\nimport { findDocsPlugin } from '@/cli/utils.ts';\nimport { autoExportMcp } from './mcp-export.ts';\nimport { scanRepo } from './scan.ts';\n\nexport async function cmdIndex(): Promise<void> {\n const positional = stripFlags(args);\n const repoPath = positional[1] || '.';\n const force = hasFlag('force');\n const depth = parseInt(getFlag('depth') || '500', 10);\n const onlyRaw = getFlag('only');\n const docsPath = getFlag('docs');\n const skipPrompt = hasFlag('yes') || hasFlag('y');\n\n\n const scan = scanRepo(repoPath);\n printScanTree(scan, depth);\n\n\n let modules: string[];\n\n if (onlyRaw) {\n // --only flag: explicit module selection\n modules = onlyRaw.split(',').map(s => s.trim());\n } else if (scan.config.plugins && scan.config.plugins.length > 0) {\n // Config exists with plugins field — use it as source of truth\n modules = scan.config.plugins;\n console.log(c.dim(`\\n Using config: plugins = [${modules.join(', ')}]\\n`));\n } else if (skipPrompt) {\n modules = buildDefaultModules(scan);\n } else {\n modules = await promptModules(scan);\n if (modules.length === 0) {\n console.log(c.dim('\\n Nothing selected. Exiting.\\n'));\n return;\n }\n\n // Clean screen and show selection summary\n console.clear();\n console.log(c.bold('\\n━━━ BrainBank ━━━\\n'));\n console.log(' Selected modules:');\n for (const m of modules) {\n console.log(` ${c.green('✓')} ${m}`);\n }\n console.log('');\n }\n\n // If --docs is passed, auto-include 'docs' in modules\n if (docsPath && !modules.includes('docs')) {\n modules.push('docs');\n }\n\n // Auto-generate config.json if it doesn't exist yet\n if (!scan.config.exists && !skipPrompt) {\n await saveConfig(scan.repoPath, modules);\n }\n\n\n console.log(c.bold(`\\n━━━ Indexing: ${modules.join(', ')} ━━━`));\n\n const brain = await createBrain(repoPath);\n await brain.initialize();\n\n const config = await getConfig(repoPath);\n await registerConfigCollections(brain, repoPath, config);\n\n if (docsPath) {\n const absDocsPath = path.resolve(docsPath);\n const collName = path.basename(absDocsPath);\n try {\n const docsPlugin = findDocsPlugin(brain);\n await docsPlugin?.addCollection({\n name: collName,\n path: absDocsPath,\n pattern: '**/*.md',\n ignore: ['deprecated/**', 'node_modules/**'],\n });\n console.log(c.dim(` Registered docs collection: ${collName}`));\n } catch {\n console.log(c.yellow(` Warning: docs module not loaded, skipping --docs`));\n }\n }\n\n const result = await brain.index({\n modules,\n forceReindex: force,\n pluginOptions: { depth },\n onProgress: (stage, msg) => {\n process.stdout.write(`\\r ${c.cyan(stage.toUpperCase())} ${msg} `);\n },\n });\n\n console.log('\\n');\n for (const [name, value] of Object.entries(result)) {\n if (!value) continue;\n const v = value as Record<string, unknown>;\n if (typeof v.indexed === 'number') {\n const parts = [`${v.indexed} indexed`, `${v.skipped ?? 0} skipped`];\n if (typeof v.chunks === 'number') parts.push(`${v.chunks} chunks`);\n if (typeof v.removed === 'number' && v.removed > 0) parts.push(`${v.removed} removed`);\n console.log(` ${c.green(name)}: ${parts.join(', ')}`);\n } else {\n console.log(` ${c.green(name)}: done`);\n }\n }\n\n const stats = brain.stats();\n console.log(`\\n ${c.bold('Totals')}:`);\n for (const [name, s] of Object.entries(stats)) {\n if (!s || typeof s !== 'object') continue;\n const entries = Object.entries(s as Record<string, unknown>)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ');\n console.log(` ${name}: ${entries}`);\n }\n\n brain.close();\n\n // Auto-export MCP config to Antigravity if detected and not already configured\n await autoExportMcp(repoPath);\n}\n\n\nfunction printScanTree(scan: ScanResult, depth: number): void {\n console.clear();\n console.log(c.bold('\\n━━━ BrainBank Scan ━━━'));\n console.log(c.dim(` Repo: ${scan.repoPath}`));\n\n // Multi-repo detection\n if (scan.gitSubdirs.length > 0) {\n console.log(c.cyan(`\\n 🔀 Multi-repo — ${scan.gitSubdirs.length} git repos detected`));\n for (const sub of scan.gitSubdirs) {\n console.log(c.dim(` └── ${sub.name}`));\n }\n }\n\n // Dynamic module display\n for (const mod of scan.modules) {\n console.log('');\n if (mod.available) {\n const extra = mod.name === 'git' ? ` (depth: ${depth})` : '';\n console.log(` ${mod.icon} ${c.bold(capitalizeFirst(mod.name))} — ${mod.summary}${extra}`);\n if (mod.details) {\n for (const d of mod.details) {\n console.log(c.dim(` ${d}`));\n }\n }\n } else {\n console.log(` ${mod.icon} ${c.dim(`${capitalizeFirst(mod.name)} — ${mod.summary}`)}`);\n }\n }\n\n // Config ignore\n if (scan.config.ignore?.length) {\n console.log(c.dim(` Ignore: ${scan.config.ignore.join(', ')}`));\n }\n\n // Config & DB\n console.log('');\n if (scan.config.exists) {\n console.log(` ⚙️ ${c.dim('Config:')} .brainbank/config.json ${c.green('✓')}`);\n }\n if (scan.db?.exists) {\n const ago = scan.db.lastModified ? timeSince(scan.db.lastModified) : '';\n console.log(` 💾 ${c.dim('DB:')} ${scan.db.sizeMB} MB${ago ? `, last indexed ${ago}` : ''}`);\n } else {\n console.log(` 💾 ${c.dim('DB: new (first index)')}`);\n }\n console.log('');\n}\n\n\n/** Build the default list of available modules based on scan. */\nfunction buildDefaultModules(scan: ScanResult): string[] {\n return scan.modules.filter(m => m.available && m.checked).map(m => m.name);\n}\n\n/** Interactive checkbox prompt via @inquirer/prompts. */\nasync function promptModules(scan: ScanResult): Promise<string[]> {\n const { checkbox } = await import('@inquirer/prompts');\n console.log(c.dim(' ─────────────────────────────────────────\\n'));\n\n const choices = scan.modules.map((m: ScanModule) => ({\n name: `${capitalizeFirst(m.name).padEnd(6)} — ${m.summary}`,\n value: m.name,\n checked: m.checked && m.available,\n disabled: m.available ? undefined : m.disabled,\n }));\n\n return checkbox<string>({\n message: 'Select modules to index:\\n',\n choices,\n });\n}\n\n\nfunction timeSince(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n if (seconds < 60) return 'just now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\n/** Capitalize first letter. */\nfunction capitalizeFirst(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Generate .brainbank/config.json from the selected modules. */\nasync function saveConfig(repoPath: string, modules: string[]): Promise<void> {\n const { select, confirm } = await import('@inquirer/prompts');\n\n // Embedding provider selection\n const envEmbedding = process.env.BRAINBANK_EMBEDDING;\n const embedding = await select<string>({\n message: 'Embedding provider:',\n choices: [\n {\n name: 'perplexity-context — best accuracy (recommended)',\n value: 'perplexity-context',\n },\n {\n name: 'perplexity — fast, high quality',\n value: 'perplexity',\n },\n {\n name: 'openai — text-embedding-3-small',\n value: 'openai',\n },\n {\n name: 'local — offline, no API key needed',\n value: 'local',\n },\n ],\n default: envEmbedding ?? 'perplexity-context',\n });\n\n // Pruner selection\n const pruner = await select<string>({\n message: 'Noise pruner:',\n choices: [\n {\n name: 'haiku — AI-powered noise filter (recommended)',\n value: 'haiku',\n },\n {\n name: 'none — no pruning',\n value: 'none',\n },\n ],\n default: 'haiku',\n });\n\n const configDir = path.join(repoPath, '.brainbank');\n const configPath = path.join(configDir, 'config.json');\n\n const config: Record<string, unknown> = {\n plugins: modules,\n embedding,\n };\n\n if (pruner !== 'none') {\n config.pruner = pruner;\n }\n\n // Key management: detect available keys and offer to save\n const detectedKeys: Record<string, string> = {};\n const needsPerplexity = embedding.startsWith('perplexity');\n const needsAnthropic = pruner === 'haiku';\n const needsOpenai = embedding === 'openai';\n\n if (needsPerplexity && process.env.PERPLEXITY_API_KEY) {\n detectedKeys.perplexity = process.env.PERPLEXITY_API_KEY;\n }\n if (needsAnthropic && process.env.ANTHROPIC_API_KEY) {\n detectedKeys.anthropic = process.env.ANTHROPIC_API_KEY;\n }\n if (needsOpenai && process.env.OPENAI_API_KEY) {\n detectedKeys.openai = process.env.OPENAI_API_KEY;\n }\n\n if (Object.keys(detectedKeys).length > 0) {\n const keyNames = Object.keys(detectedKeys).join(', ');\n const saveKeys = await confirm({\n message: `Save API keys (${keyNames}) to config.json? (portable, no env vars needed)`,\n default: true,\n });\n if (saveKeys) {\n config.keys = detectedKeys;\n }\n }\n\n fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n');\n console.log(c.green(` ✓ Saved ${path.relative(process.cwd(), configPath)}`));\n}\n\n","/**\n * brainbank mcp:export [target] — Export MCP server config for AI IDEs.\n *\n * Generates the MCP server config block for brainbank and merges it into\n * the target IDE's config file. Currently supports: antigravity.\n *\n * Detects: node path, cli.js path, API keys from config or env vars.\n */\n\nimport type { ProjectConfig } from '@/cli/factory/config-loader.ts';\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { c, args, getFlag } from '@/cli/utils.ts';\nimport { getConfig } from '@/cli/factory/index.ts';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/** Supported export targets and their config file paths. */\nconst TARGETS: Record<string, { configPath: string; label: string }> = {\n antigravity: {\n configPath: path.join(process.env.HOME ?? '~', '.gemini', 'antigravity', 'mcp_config.json'),\n label: 'Gemini Antigravity',\n },\n};\n\ninterface McpServerConfig {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\ninterface McpConfig {\n mcpServers: Record<string, McpServerConfig>;\n}\n\n/**\n * Build the brainbank MCP server config block.\n * Resolves node binary, dist/cli.js path, and API keys.\n */\nfunction buildBrainbankMcpBlock(config: ProjectConfig | null): McpServerConfig {\n const nodeBin = process.execPath;\n\n // Resolve dist/cli.js from the global install location (node_prefix/lib/node_modules/brainbank/dist/cli.js)\n const globalCliJs = path.join(path.dirname(nodeBin), '..', 'lib', 'node_modules', 'brainbank', 'dist', 'cli.js');\n // Fallback: relative to this file (dev / npm link)\n const localCliJs = path.resolve(__dirname, '..', '..', 'dist', 'cli.js');\n const resolvedCliJs = fs.existsSync(globalCliJs) ? globalCliJs : localCliJs;\n\n const env: Record<string, string> = {};\n\n // Resolve API keys: config.keys > env vars\n const keys = config?.keys;\n const perplexityKey = keys?.perplexity ?? process.env.PERPLEXITY_API_KEY;\n const anthropicKey = keys?.anthropic ?? process.env.ANTHROPIC_API_KEY;\n const openaiKey = keys?.openai ?? process.env.OPENAI_API_KEY;\n\n if (perplexityKey) env.PERPLEXITY_API_KEY = perplexityKey;\n if (anthropicKey) env.ANTHROPIC_API_KEY = anthropicKey;\n if (openaiKey) env.OPENAI_API_KEY = openaiKey;\n\n const block: McpServerConfig = {\n command: nodeBin,\n args: ['--disable-warning=ExperimentalWarning', resolvedCliJs, 'mcp'],\n };\n\n if (Object.keys(env).length > 0) {\n block.env = env;\n }\n\n return block;\n}\n\n/**\n * Load existing MCP config, merge brainbank entry, and write back.\n * Preserves all other server entries.\n */\nfunction mergeAndWrite(targetPath: string, block: McpServerConfig): { created: boolean } {\n let existing: McpConfig = { mcpServers: {} };\n const created = !fs.existsSync(targetPath);\n\n if (!created) {\n try {\n const raw = fs.readFileSync(targetPath, 'utf-8');\n existing = JSON.parse(raw) as McpConfig;\n if (!existing.mcpServers) existing.mcpServers = {};\n } catch {\n // Corrupt or empty file — start fresh\n existing = { mcpServers: {} };\n }\n }\n\n existing.mcpServers.brainbank = block;\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, JSON.stringify(existing, null, 2) + '\\n');\n\n return { created };\n}\n\n/** Check if an MCP config already has a brainbank entry. */\nexport function hasBrainbankMcpEntry(targetPath: string): boolean {\n if (!fs.existsSync(targetPath)) return false;\n try {\n const raw = fs.readFileSync(targetPath, 'utf-8');\n const config = JSON.parse(raw) as McpConfig;\n return !!config.mcpServers?.brainbank;\n } catch {\n return false;\n }\n}\n\n/** Auto-export: called after index when Antigravity is detected. */\nexport async function autoExportMcp(repoPath: string): Promise<void> {\n const target = TARGETS.antigravity;\n if (!target) return;\n\n // Only auto-export if Antigravity dir exists\n const antigravityDir = path.dirname(target.configPath);\n if (!fs.existsSync(antigravityDir)) return;\n\n // Only auto-export if brainbank isn't already configured\n if (hasBrainbankMcpEntry(target.configPath)) return;\n\n const config = await getConfig(repoPath);\n const block = buildBrainbankMcpBlock(config);\n mergeAndWrite(target.configPath, block);\n console.log(` ${c.green('✓')} Exported MCP config to ${c.dim(path.relative(process.env.HOME ?? '', target.configPath))}`);\n}\n\n// ── GEMINI.md BrainBank Section ──────────────────────────────\n\nconst BRAINBANK_SECTION_MARKER = '<!-- brainbank:start -->';\nconst BRAINBANK_SECTION_END = '<!-- brainbank:end -->';\n\n/** Global GEMINI.md path — ~/.gemini/GEMINI.md (shared across all projects). */\nconst GLOBAL_GEMINI = path.join(process.env.HOME ?? '~', '.gemini', 'GEMINI.md');\n\nfunction buildGeminiSection(): string {\n return `${BRAINBANK_SECTION_MARKER}\n\n## BrainBank — Code Intelligence\n\nWhen \\`brainbank_context\\` and \\`brainbank_files\\` MCP tools are available, **always use them instead of \\`grep_search\\` or \\`list_dir\\`**.\n\n**\\`brainbank_context\\`** — semantic search. \\`repo\\` is **required** (the project root where \\`brainbank index\\` was run). Use \\`path:\\` to scope within it, \\`compact: false\\`, \\`sources: { code: 25, docs: 0, git: 0 }\\`.\n\n**\\`brainbank_files\\`** — read full indexed files (\\`lines: true\\` always). Only works with files tracked by the index — for \\`.env\\`, \\`docker-compose.yml\\`, etc. use \\`view_file\\`.\n\n**Sources rule:** Default to code-only (\\`docs: 0\\`). Only add \\`docs\\` when the user explicitly asks about documentation. Never mix code and docs in the same query — fire separate queries.\n\n### Output handling (critical)\n\nBrainBank may return results **inline** or save them to an **output file**:\n\n- **Inline:** read and proceed normally.\n- **File result** (saved to \\`output.txt\\`): show the path as a clickable link, ask user to paste, then **STOP and WAIT**:\n\n 📋 Output: [output.txt](file:///path/to/output.txt) — _\"Could you paste the context output here?\"_\n\n Do **NOT** read the file yourself. Wait for the paste before proceeding.\n\n${BRAINBANK_SECTION_END}\n`;\n}\n\n/** Check if GEMINI.md already has the brainbank section. */\nfunction hasGeminiSection(geminiPath: string): boolean {\n if (!fs.existsSync(geminiPath)) return false;\n const content = fs.readFileSync(geminiPath, 'utf-8');\n return content.includes(BRAINBANK_SECTION_MARKER);\n}\n\n/** Append BrainBank section to GEMINI.md (creates if doesn't exist). */\nfunction appendGeminiSection(geminiPath: string): void {\n const section = buildGeminiSection();\n if (fs.existsSync(geminiPath)) {\n fs.appendFileSync(geminiPath, section);\n } else {\n fs.writeFileSync(geminiPath, `# GEMINI.md\\n${section}`);\n }\n}\n\n/** Replace BrainBank section between markers in GEMINI.md. */\nfunction replaceGeminiSection(geminiPath: string): void {\n const content = fs.readFileSync(geminiPath, 'utf-8');\n const startIdx = content.indexOf(BRAINBANK_SECTION_MARKER);\n const endIdx = content.indexOf(BRAINBANK_SECTION_END);\n if (startIdx === -1 || endIdx === -1) return;\n\n const before = content.slice(0, startIdx);\n const after = content.slice(endIdx + BRAINBANK_SECTION_END.length);\n const section = buildGeminiSection();\n fs.writeFileSync(geminiPath, before + section + after);\n}\n\n/** CLI command: brainbank mcp:export [target] [--force] */\nexport async function cmdMcpExport(): Promise<void> {\n const targetName = args[1] || getFlag('target') || 'antigravity';\n const repoPath = getFlag('repo') || '.';\n const force = args.includes('--force') || args.includes('-f');\n\n const target = TARGETS[targetName];\n if (!target) {\n console.error(c.red(`Unknown export target: ${targetName}`));\n console.error(c.dim(` Available: ${Object.keys(TARGETS).join(', ')}`));\n process.exit(1);\n }\n\n const config = await getConfig(repoPath);\n const block = buildBrainbankMcpBlock(config);\n\n console.log(c.bold(`\\n━━━ MCP Export: ${target.label} ━━━\\n`));\n\n // ── MCP Config ────────────────────────────────────────────\n const mcpExists = hasBrainbankMcpEntry(target.configPath);\n let writeMcp = true;\n\n if (mcpExists && !force) {\n console.log(` ${c.yellow('●')} MCP config already has brainbank entry`);\n const cliPath = block.args.find(a => !a.startsWith('--')) ?? block.args[0];\n console.log(` ${c.dim(' New:')} ${block.command} ${cliPath}`);\n const envKeys = block.env ? Object.keys(block.env) : [];\n if (envKeys.length > 0) console.log(` ${c.dim(' Keys:')} ${envKeys.join(', ')}`);\n const { confirm } = await import('@inquirer/prompts');\n writeMcp = await confirm({ message: 'Override existing brainbank MCP entry?', default: true });\n }\n\n if (writeMcp) {\n const { created } = mergeAndWrite(target.configPath, block);\n console.log(` ${c.green('✓')} ${created ? 'Created' : 'Updated'} ${c.dim(target.configPath)}`);\n } else {\n console.log(` ${c.dim('MCP config — skipped')}`);\n }\n\n // ── Global GEMINI.md (~/.gemini/GEMINI.md) ────────────────\n const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);\n\n if (geminiHasSection) {\n if (force) {\n replaceGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);\n } else {\n console.log(` ${c.yellow('●')} ~/.gemini/GEMINI.md already has BrainBank section`);\n const { confirm } = await import('@inquirer/prompts');\n const override = await confirm({ message: 'Override existing BrainBank section?', default: false });\n if (override) {\n replaceGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);\n } else {\n console.log(` ${c.dim('GEMINI.md — skipped')}`);\n }\n }\n } else {\n if (force) {\n appendGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);\n } else {\n const { confirm } = await import('@inquirer/prompts');\n const addGemini = await confirm({\n message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',\n default: true,\n });\n if (addGemini) {\n appendGeminiSection(GLOBAL_GEMINI);\n console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);\n }\n }\n }\n\n console.log(`\\n ${c.dim('Restart your IDE to apply changes.')}\\n`);\n}\n","/**\n * brainbank scan — Lightweight repo scanner for the interactive index flow.\n *\n * Scans the filesystem WITHOUT initializing BrainBank. Returns a ScanResult\n * describing what's available to index via dynamic ScanModule descriptors.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { SUPPORTED_EXTENSIONS, isIgnoredDir, isIgnoredFile } from '@/lib/languages.ts';\n\n\n/** A single scannable module (plugin). */\nexport interface ScanModule {\n /** Plugin name (e.g. 'code', 'git', 'docs'). */\n name: string;\n /** Whether there's content available to index. */\n available: boolean;\n /** Human-readable summary (e.g. '1243 files (5 languages)'). */\n summary: string;\n /** Emoji icon for display. */\n icon: string;\n /** Whether checked by default in the prompt. */\n checked: boolean;\n /** Reason this module is disabled (shown in prompt). */\n disabled?: string;\n /** Detail lines for the scan tree (e.g. per-language breakdown). */\n details?: string[];\n}\n\nexport interface ScanResult {\n repoPath: string;\n modules: ScanModule[];\n config: { exists: boolean; ignore?: string[]; plugins?: string[] };\n db: { exists: boolean; sizeMB: number; lastModified?: Date } | null;\n gitSubdirs: { name: string }[];\n}\n\n\n/** Scan a repo path and return what's available to index. */\nexport function scanRepo(repoPath: string): ScanResult {\n const resolved = path.resolve(repoPath);\n const gitSubdirs = scanGitSubdirs(resolved);\n\n return {\n repoPath: resolved,\n modules: scanModules(resolved, gitSubdirs),\n config: scanConfig(resolved),\n db: scanDb(resolved),\n gitSubdirs,\n };\n}\n\n/** Produce ScanModule descriptors for known plugin types. */\nfunction scanModules(repoPath: string, gitSubdirs: { name: string }[]): ScanModule[] {\n return [\n scanCodeModule(repoPath),\n scanGitModule(repoPath, gitSubdirs),\n scanDocsModule(repoPath),\n ];\n}\n\n\n/** Scan for indexable code files. */\nfunction scanCodeModule(repoPath: string): ScanModule {\n const byLanguage = new Map<string, number>();\n let total = 0;\n\n function walk(dir: string): void {\n let entries: fs.Dirent[];\n try { entries = fs.readdirSync(dir, { withFileTypes: true }); }\n catch { return; }\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const isDir = entry.isDirectory() || (entry.isSymbolicLink() && (() => { try { return fs.statSync(fullPath).isDirectory(); } catch { return false; } })());\n if (isDir) {\n if (isIgnoredDir(entry.name)) continue;\n walk(fullPath);\n } else if (entry.isFile()) {\n if (isIgnoredFile(entry.name)) continue;\n const ext = path.extname(entry.name).toLowerCase();\n const lang = SUPPORTED_EXTENSIONS[ext];\n if (!lang) continue;\n byLanguage.set(lang, (byLanguage.get(lang) ?? 0) + 1);\n total++;\n }\n }\n }\n\n walk(repoPath);\n\n if (total === 0) {\n return { name: 'code', available: false, summary: 'no supported source files found', icon: '📁', checked: false, disabled: 'nothing to index' };\n }\n\n const langCount = byLanguage.size;\n const sorted = [...byLanguage.entries()].sort((a, b) => b[1] - a[1]);\n const maxShow = 7;\n const shown = sorted.slice(0, maxShow);\n const remaining = sorted.length - maxShow;\n\n const details: string[] = [];\n for (let i = 0; i < shown.length; i++) {\n const [lang, count] = shown[i];\n const isLast = i === shown.length - 1 && remaining <= 0;\n const prefix = isLast ? '└──' : '├──';\n details.push(`${prefix} ${lang.padEnd(14)} ${count} files`);\n }\n if (remaining > 0) {\n details.push(`└── ...and ${remaining} more`);\n }\n\n return {\n name: 'code',\n available: true,\n summary: `${total} files (${langCount} language${langCount > 1 ? 's' : ''})`,\n icon: '📁',\n checked: true,\n details,\n };\n}\n\n/** Scan for git history. */\nfunction scanGitModule(repoPath: string, gitSubdirs: { name: string }[]): ScanModule {\n const stats = scanGitStats(repoPath, gitSubdirs);\n\n if (!stats) {\n return { name: 'git', available: false, summary: 'no .git directory found', icon: '📜', checked: false, disabled: 'not a git repo' };\n }\n\n const details: string[] = [];\n if (stats.lastMessage) {\n details.push(`Last: ${stats.lastMessage} (${stats.lastDate})`);\n }\n\n return {\n name: 'git',\n available: true,\n summary: `${stats.commitCount.toLocaleString()} commits`,\n icon: '📜',\n checked: true,\n details,\n };\n}\n\n/** Scan for document collections. */\nfunction scanDocsModule(repoPath: string): ScanModule {\n const collections = scanDocsCollections(repoPath);\n\n if (collections.length === 0) {\n return { name: 'docs', available: false, summary: 'no documents found', icon: '📄', checked: false, disabled: 'no .md/.mdx files' };\n }\n\n const totalFiles = collections.reduce((s, d) => s + d.fileCount, 0);\n const details = collections.map((d, i) => {\n const isLast = i === collections.length - 1;\n const prefix = isLast ? '└──' : '├──';\n return `${prefix} ${d.name.padEnd(10)} → ${d.path} (${d.fileCount} files)`;\n });\n\n return {\n name: 'docs',\n available: true,\n summary: `${collections.length} collection${collections.length > 1 ? 's' : ''} (${totalFiles} files)`,\n icon: '📄',\n checked: true,\n details,\n };\n}\n\n\n/** Get git stats. Supports single repo and multi-repo aggregation. */\nfunction scanGitStats(repoPath: string, gitSubdirs: { name: string }[]): { commitCount: number; lastMessage: string; lastDate: string } | null {\n if (fs.existsSync(path.join(repoPath, '.git'))) {\n return gitStats(repoPath);\n }\n\n if (gitSubdirs.length === 0) return null;\n\n let totalCommits = 0;\n let latestMessage = '';\n let latestDate = '';\n\n for (const sub of gitSubdirs) {\n const stats = gitStats(path.join(repoPath, sub.name));\n if (stats) {\n totalCommits += stats.commitCount;\n if (!latestMessage) {\n latestMessage = stats.lastMessage;\n latestDate = stats.lastDate;\n }\n }\n }\n\n return totalCommits > 0\n ? { commitCount: totalCommits, lastMessage: latestMessage, lastDate: latestDate }\n : null;\n}\n\n/** Get git stats for a single directory. */\nfunction gitStats(dir: string): { commitCount: number; lastMessage: string; lastDate: string } | null {\n try {\n const count = parseInt(execSync('git rev-list --count HEAD', { cwd: dir, encoding: 'utf-8' }).trim(), 10);\n const log = execSync('git log -1 --format=\"%s|%ar\"', { cwd: dir, encoding: 'utf-8' }).trim();\n const [lastMessage, lastDate] = log.split('|');\n return { commitCount: count, lastMessage: lastMessage ?? '', lastDate: lastDate ?? '' };\n } catch {\n return null;\n }\n}\n\n/** Scan for document collections (config + auto-detect). */\nfunction scanDocsCollections(repoPath: string): { name: string; path: string; fileCount: number }[] {\n const results: { name: string; path: string; fileCount: number }[] = [];\n const seen = new Set<string>();\n\n // 1. Read explicit collections from config.json\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n try {\n if (fs.existsSync(configPath)) {\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const docsCfg = config?.docs as Record<string, unknown> | undefined;\n const collections = docsCfg?.collections as { name: string; path: string }[] | undefined;\n if (collections) {\n for (const coll of collections) {\n const absPath = path.resolve(repoPath, coll.path);\n results.push({ name: coll.name, path: coll.path, fileCount: countDocs(absPath) });\n seen.add(absPath);\n }\n }\n }\n } catch {}\n\n // 2. Auto-detect .md/.mdx in the repo root and top-level dirs\n const rootDocs = countDocsShallow(repoPath);\n if (rootDocs > 0) {\n results.push({ name: '(root)', path: '.', fileCount: rootDocs });\n }\n\n try {\n for (const entry of fs.readdirSync(repoPath, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n if (isIgnoredDir(entry.name)) continue;\n if (entry.name.startsWith('.')) continue;\n\n const dirPath = path.join(repoPath, entry.name);\n if (seen.has(dirPath)) continue;\n\n const count = countDocs(dirPath);\n if (count > 0) {\n results.push({ name: entry.name, path: `./${entry.name}`, fileCount: count });\n }\n }\n } catch {}\n\n return results;\n}\n\n/** Count .md/.mdx files recursively in a directory. */\nfunction countDocs(dir: string): number {\n let count = 0;\n try {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n const ePath = path.join(dir, e.name);\n const isDir = e.isDirectory() || (e.isSymbolicLink() && (() => { try { return fs.statSync(ePath).isDirectory(); } catch { return false; } })());\n if (isDir) {\n if (isIgnoredDir(e.name)) continue;\n count += countDocs(ePath);\n } else if ((e.isFile() || e.isSymbolicLink()) && /\\.mdx?$/i.test(e.name)) {\n count++;\n }\n }\n } catch {}\n return count;\n}\n\n/** Count .md/.mdx files in a directory (non-recursive, root level only). */\nfunction countDocsShallow(dir: string): number {\n let count = 0;\n try {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n if (e.isFile() && /\\.mdx?$/i.test(e.name)) count++;\n }\n } catch {}\n return count;\n}\n\n/** Check if config.json exists and read key fields. */\nfunction scanConfig(repoPath: string): ScanResult['config'] {\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n if (!fs.existsSync(configPath)) return { exists: false };\n\n try {\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const codeCfg = config?.code as Record<string, unknown> | undefined;\n return {\n exists: true,\n ignore: codeCfg?.ignore as string[] | undefined,\n plugins: config?.plugins as string[] | undefined,\n };\n } catch {\n return { exists: false };\n }\n}\n\n/** Check DB existence and size. */\nfunction scanDb(repoPath: string): ScanResult['db'] {\n const dbPath = path.join(repoPath, '.brainbank', 'data', 'brainbank.db');\n if (!fs.existsSync(dbPath)) return { exists: false, sizeMB: 0 };\n\n try {\n const stat = fs.statSync(dbPath);\n return {\n exists: true,\n sizeMB: Math.round(stat.size / 1024 / 1024 * 10) / 10,\n lastModified: stat.mtime,\n };\n } catch {\n return { exists: false, sizeMB: 0 };\n }\n}\n\n/** Detect subdirectories with their own .git (mono-repo). Respects `repos` whitelist from config. */\nfunction scanGitSubdirs(repoPath: string): ScanResult['gitSubdirs'] {\n if (fs.existsSync(path.join(repoPath, '.git'))) return [];\n\n try {\n let subdirs = fs.readdirSync(repoPath, { withFileTypes: true })\n .filter(e => {\n if (e.name.startsWith('.')) return false;\n const isDir = e.isDirectory() || (e.isSymbolicLink() && (() => { try { return fs.statSync(path.join(repoPath, e.name)).isDirectory(); } catch { return false; } })());\n return isDir;\n })\n .filter(e => fs.existsSync(path.join(repoPath, e.name, '.git')))\n .map(e => ({ name: e.name }));\n\n // Apply repos whitelist from config if present\n const configRepos = readReposFromConfig(repoPath);\n if (configRepos) {\n subdirs = subdirs.filter(s => configRepos.includes(s.name));\n }\n\n return subdirs;\n } catch {\n return [];\n }\n}\n\n/** Read the `repos` whitelist from .brainbank/config.json. Returns null if not set. */\nfunction readReposFromConfig(repoPath: string): string[] | null {\n const configPath = path.join(repoPath, '.brainbank', 'config.json');\n try {\n if (!fs.existsSync(configPath)) return null;\n const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>;\n const repos = config.repos;\n if (Array.isArray(repos) && repos.every(r => typeof r === 'string')) {\n return repos as string[];\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * brainbank collection add|list|remove — Document collection management\n */\n\nimport { c, args, getFlag, stripFlags, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdCollection(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n if (sub === 'add') {\n const path = pos[2];\n const name = getFlag('name');\n const pattern = getFlag('pattern') ?? '**/*.md';\n const context = getFlag('context');\n const ignoreRaw = getFlag('ignore');\n\n if (!path || !name) {\n console.log(c.red('Usage: brainbank collection add <path> --name <name> [--pattern \"**/*.md\"] [--ignore \"glob\"] [--context \"description\"]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded. Install @brainbank/docs.')); process.exit(1); }\n await docsPlugin.addCollection({\n name,\n path,\n pattern,\n ignore: ignoreRaw ? ignoreRaw.split(',') : [],\n context: context ?? undefined,\n });\n console.log(c.green(`✓ Collection '${name}' added: ${path} (${pattern})`));\n if (context) console.log(c.dim(` Context: ${context}`));\n brain.close();\n return;\n }\n\n if (sub === 'list') {\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.yellow(' Docs plugin not loaded.')); brain.close(); return; }\n const collections = docsPlugin.listCollections();\n if (collections.length === 0) {\n console.log(c.yellow(' No collections registered.'));\n } else {\n console.log(c.bold('\\n━━━ Collections ━━━\\n'));\n for (const col of collections) {\n console.log(` ${c.cyan(col.name)} ${c.dim('→')} ${col.path}`);\n console.log(` Pattern: ${col.pattern ?? '**/*.md'}`);\n if (col.context) console.log(` Context: ${c.dim(col.context)}`);\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'remove') {\n const name = pos[2];\n if (!name) {\n console.log(c.red('Usage: brainbank collection remove <name>'));\n process.exit(1);\n }\n const brain = await createBrain();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded.')); process.exit(1); }\n await docsPlugin.removeCollection(name);\n console.log(c.green(`✓ Collection '${name}' removed.`));\n brain.close();\n return;\n }\n\n console.log(c.red('Usage: brainbank collection <add|list|remove>'));\n process.exit(1);\n}\n","/**\n * brainbank kv add|search|list|trim|clear — Dynamic KV collection management\n */\n\nimport { c, args, getFlag, stripFlags } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdKv(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n if (sub === 'add') {\n const collName = pos[2];\n const content = pos.slice(3).join(' ');\n const metaRaw = getFlag('meta');\n\n if (!collName || !content) {\n console.log(c.red(\"Usage: brainbank kv add <collection> <content> [--meta '{\\\"key\\\":\\\"val\\\"}']\"));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const meta = metaRaw ? JSON.parse(metaRaw) : {};\n const id = await coll.add(content, meta);\n console.log(c.green(`✓ Added item #${id} to '${collName}'`));\n brain.close();\n return;\n }\n\n if (sub === 'search') {\n const collName = pos[2];\n const query = pos.slice(3).join(' ');\n const k = parseInt(getFlag('k') || '5', 10);\n const mode = (getFlag('mode') || 'hybrid') as 'hybrid' | 'vector' | 'keyword';\n\n if (!collName || !query) {\n console.log(c.red('Usage: brainbank kv search <collection> <query> [--k 5] [--mode hybrid|keyword|vector]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const results = await coll.search(query, { k, mode });\n\n if (results.length === 0) {\n console.log(c.yellow(' No results found.'));\n } else {\n console.log(c.bold(`\\n━━━ ${collName}: \"${query}\" ━━━\\n`));\n for (const r of results) {\n const score = Math.round((r.score ?? 0) * 100);\n console.log(` ${c.cyan(`[${score}%]`)} ${r.content}`);\n if (Object.keys(r.metadata).length > 0) {\n console.log(` ${c.dim(JSON.stringify(r.metadata))}`);\n }\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'list') {\n const collName = pos[2];\n const limit = parseInt(getFlag('limit') || '20', 10);\n\n if (!collName) {\n const brain = await createBrain();\n await brain.initialize();\n const names = brain.listCollectionNames();\n if (names.length === 0) {\n console.log(c.yellow(' No KV collections found.'));\n } else {\n console.log(c.bold('\\n━━━ KV Collections ━━━\\n'));\n for (const n of names) {\n const coll = brain.collection(n);\n console.log(` ${c.cyan(n)} — ${coll.count()} items`);\n }\n }\n brain.close();\n return;\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const items = coll.list({ limit });\n if (items.length === 0) {\n console.log(c.yellow(` Collection '${collName}' is empty.`));\n } else {\n console.log(c.bold(`\\n━━━ ${collName} (${coll.count()} items) ━━━\\n`));\n for (const item of items) {\n const age = Math.round((Date.now() / 1000 - item.createdAt) / 60);\n console.log(` #${item.id} ${c.dim(`(${age}m ago)`)} ${item.content.slice(0, 80)}`);\n }\n }\n brain.close();\n return;\n }\n\n if (sub === 'trim') {\n const collName = pos[2];\n const keep = parseInt(getFlag('keep') || '0', 10);\n\n if (!collName || keep <= 0) {\n console.log(c.red('Usage: brainbank kv trim <collection> --keep <n>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const result = await coll.trim({ keep });\n console.log(c.green(`✓ Trimmed ${result.removed} items from '${collName}' (kept ${keep})`));\n brain.close();\n return;\n }\n\n if (sub === 'clear') {\n const collName = pos[2];\n if (!collName) {\n console.log(c.red('Usage: brainbank kv clear <collection>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const coll = brain.collection(collName);\n const before = coll.count();\n coll.clear();\n console.log(c.green(`✓ Cleared ${before} items from '${collName}'`));\n brain.close();\n return;\n }\n\n console.log(c.red('Usage: brainbank kv <add|search|list|trim|clear>'));\n process.exit(1);\n}\n\n","/**\n * brainbank docs — Index document collections\n * brainbank dsearch — Search documents only\n */\n\nimport { c, args, getFlag, stripFlags, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdDocs(): Promise<void> {\n const collection = getFlag('collection');\n const brain = await createBrain();\n\n console.log(c.bold('\\n━━━ BrainBank Docs Index ━━━\\n'));\n\n const opts: { collections?: string[]; onProgress?: (collection: string, file: string, current: number, total: number) => void } = {};\n if (collection) opts.collections = [collection];\n opts.onProgress = (col: string, file: string, cur: number, total: number) => {\n process.stdout.write(`\\r ${c.cyan(col)} [${cur}/${total}] ${file} `);\n };\n\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red(' Docs plugin not loaded. Install @brainbank/docs.')); process.exit(1); }\n\n const results = await docsPlugin.indexDocs(opts);\n\n console.log('\\n');\n for (const [name, stat] of Object.entries(results) as [string, { indexed: number; skipped: number; removed: number; chunks: number }][]) {\n const removedStr = stat.removed > 0 ? `, ${c.red(String(stat.removed) + ' removed')}` : '';\n console.log(` ${c.green(name)}: ${stat.indexed} indexed, ${stat.skipped} skipped${removedStr}, ${stat.chunks} chunks`);\n }\n\n brain.close();\n}\n\nexport async function cmdDocSearch(): Promise<void> {\n const query = stripFlags(args).slice(1).join(' ');\n if (!query) {\n console.log(c.red('Usage: brainbank dsearch <query>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n const collection = getFlag('collection');\n const k = parseInt(getFlag('k') || '8', 10);\n\n console.log(c.bold(`\\n━━━ BrainBank Doc Search: \"${query}\" ━━━\\n`));\n\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) {\n console.log(c.red('Docs plugin not loaded. Install @brainbank/docs.'));\n process.exit(1);\n }\n const results = await docsPlugin.search(query, { collection: collection ?? undefined, k });\n\n if (results.length === 0) {\n console.log(c.yellow(' No results found.'));\n brain.close();\n return;\n }\n\n for (const r of results) {\n const score = Math.round(r.score * 100);\n const ctx = r.context ? ` — ${c.dim(r.context)}` : '';\n console.log(`${c.magenta(`[DOC ${score}%]`)} ${c.bold(r.filePath!)} [${r.type === 'document' ? r.metadata.collection ?? '' : ''}]${ctx}`);\n const preview = r.content.split('\\n').slice(0, 4).join('\\n');\n console.log(c.dim(preview));\n console.log('');\n }\n\n brain.close();\n}\n","/**\n * brainbank search — Semantic search (vector)\n * brainbank hsearch — Hybrid search (vector + BM25)\n * brainbank ksearch — Keyword search (BM25)\n *\n * Source filtering:\n * --code 10 Max code results\n * --git 0 Skip git results\n * --docs 5 Max document results\n * --notes 10 Custom plugin results\n * --slack_messages 5 Custom collection results\n *\n * Any --<name> <number> flag is treated as a source filter.\n */\n\nimport { c, args, stripFlags, printResults } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\n/**\n * Parse dynamic source flags: each `--<name> <number>` becomes `{ name: number }`.\n *\n * Known non-source flags (--repo, --depth, etc.) are excluded.\n * Returns sources map + the query string (positional args).\n */\nfunction parseSourceFlags(): { sources: Record<string, number>; query: string } {\n const NON_SOURCE_FLAGS = new Set([\n 'repo', 'depth', 'collection', 'pattern', 'context', 'name',\n 'keep', 'reranker', 'pruner', 'only', 'docs-path', 'mode', 'limit',\n 'ignore', 'meta', 'k', 'yes', 'y', 'force', 'verbose',\n ]);\n\n const sources: Record<string, number> = {};\n const positional: string[] = [];\n\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n const name = args[i].slice(2);\n\n // Skip boolean flags\n if (name === 'yes' || name === 'force' || name === 'verbose') continue;\n\n // If next arg is a number and flag is not a known non-source flag\n const next = args[i + 1];\n if (next !== undefined && /^\\d+$/.test(next) && !NON_SOURCE_FLAGS.has(name)) {\n sources[name] = parseInt(next, 10);\n i++; // skip the value\n continue;\n }\n\n // Known value flag — skip its value\n if (NON_SOURCE_FLAGS.has(name) && next !== undefined && !next.startsWith('--')) {\n i++;\n }\n continue;\n }\n positional.push(args[i]);\n }\n\n const query = positional.slice(1).join(' '); // skip command name\n return { sources, query };\n}\n\n/** Print active source filters. */\nfunction printFilterInfo(sources: Record<string, number>): void {\n const entries = Object.entries(sources);\n if (entries.length === 0) return;\n const parts = entries.map(([k, v]) => `${k}=${v}`);\n console.log(c.dim(` Sources: ${parts.join(', ')}`));\n}\n\n/** Build search options from sources map. */\nfunction buildSearchOptions(sources: Record<string, number>): { sources: Record<string, number>; source: 'cli' } {\n return Object.keys(sources).length > 0 ? { sources, source: 'cli' } : { sources: {}, source: 'cli' };\n}\n\nexport async function cmdSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank search <query> [--code <n>] [--git <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n console.log(c.bold(`\\n━━━ BrainBank Search: \"${query}\" ━━━\\n`));\n printFilterInfo(sources);\n\n const opts = buildSearchOptions(sources);\n const results = await brain.search(query, opts);\n printResults(results);\n brain.close();\n}\n\nexport async function cmdHybridSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank hsearch <query> [--code <n>] [--git <n>] [--docs <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n console.log(c.bold(`\\n━━━ BrainBank Hybrid Search: \"${query}\" ━━━`));\n console.log(c.dim(` Mode: vector + BM25 → Reciprocal Rank Fusion`));\n printFilterInfo(sources);\n console.log('');\n\n const opts = buildSearchOptions(sources);\n const results = await brain.hybridSearch(query, opts);\n printResults(results);\n brain.close();\n}\n\nexport async function cmdKeywordSearch(): Promise<void> {\n const { sources, query } = parseSourceFlags();\n if (!query) {\n console.log(c.red('Usage: brainbank ksearch <query> [--code <n>] [--git <n>] [--<source> <n>]'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n console.log(c.bold(`\\n━━━ BrainBank Keyword Search: \"${query}\" ━━━`));\n console.log(c.dim(` Mode: BM25 full-text (instant)`));\n printFilterInfo(sources);\n console.log('');\n\n const opts = buildSearchOptions(sources);\n const results = await brain.searchBM25(query, opts);\n printResults(results);\n brain.close();\n}\n","/**\n * ServerClient — Lightweight HTTP client for the BrainBank daemon.\n *\n * Used by CLI commands to delegate to a running HTTP server\n * instead of loading models locally. Falls back gracefully\n * (returns null) if the server is unreachable.\n */\n\nimport * as http from 'node:http';\n\nimport { isServerRunning } from '@/services/daemon.ts';\n\ninterface ContextOptions {\n task: string;\n repo?: string;\n sources?: Record<string, number>;\n pathPrefix?: string;\n affectedFiles?: string[];\n}\n\n/**\n * Try to get context from the running HTTP server.\n * Returns the context string if successful, null if server is unreachable.\n */\nexport async function tryServerContext(options: ContextOptions): Promise<string | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const body = JSON.stringify({\n task: options.task,\n repo: options.repo,\n sources: options.sources,\n pathPrefix: options.pathPrefix,\n affectedFiles: options.affectedFiles,\n });\n\n const response = await httpPost(info.port, '/context', body);\n const data = JSON.parse(response) as { context?: string; error?: string };\n\n if (data.error) return null;\n return data.context ?? null;\n } catch {\n // Server unreachable or error — fall back to local\n return null;\n }\n}\n\n/**\n * Try to trigger indexing on the running HTTP server.\n * Returns the result if successful, null if server is unreachable.\n */\nexport async function tryServerIndex(repo?: string, forceReindex?: boolean): Promise<Record<string, unknown> | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const body = JSON.stringify({ repo, forceReindex });\n const response = await httpPost(info.port, '/index', body);\n const data = JSON.parse(response) as { result?: Record<string, unknown>; error?: string };\n\n if (data.error) return null;\n return data.result ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check server health. Returns health info or null.\n */\nexport async function serverHealth(): Promise<{\n ok: boolean;\n pid: number;\n port: number;\n uptime: number;\n workspaces: number;\n} | null> {\n const info = isServerRunning();\n if (!info) return null;\n\n try {\n const response = await httpGet(info.port, '/health');\n return JSON.parse(response) as { ok: boolean; pid: number; port: number; uptime: number; workspaces: number };\n } catch {\n return null;\n }\n}\n\n// ── HTTP helpers ────────────────────────────────────\n\nfunction httpPost(port: number, path: string, body: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const req = http.request({\n hostname: '127.0.0.1',\n port,\n path,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n },\n timeout: 120_000, // 2 minutes — context queries can be slow on first load\n }, (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n });\n\n req.on('error', reject);\n req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });\n req.write(body);\n req.end();\n });\n}\n\nfunction httpGet(port: number, path: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const req = http.request({\n hostname: '127.0.0.1',\n port,\n path,\n method: 'GET',\n timeout: 5_000,\n }, (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n });\n\n req.on('error', reject);\n req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });\n req.end();\n });\n}\n","/**\n * brainbank context <task> — Get formatted context for a task\n * brainbank context add <collection> <path> <description>\n * brainbank context list\n *\n * Source filtering (same as search commands):\n * --code 20 Max code results (default: 20)\n * --git 5 Max git results\n * --no-git Skip git results\n * --no-code Skip code results\n * --path <dir> Filter results to files under this path prefix\n * --ignore <paths> Exclude paths (comma-separated or repeated: --ignore a,b --ignore c)\n */\n\nimport { c, args, stripFlags, getFlag, getFlagAll, findDocsPlugin } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\nimport { tryServerContext } from '@/cli/server-client.ts';\n\n/** Parse --code N, --git N, --no-git, --no-code flags into sources map. */\nfunction parseContextFlags(): Record<string, number> {\n const NON_SOURCE = new Set([\n 'repo', 'depth', 'collection', 'pattern', 'context', 'name',\n 'keep', 'reranker', 'pruner', 'only', 'docs-path', 'mode', 'limit',\n 'ignore', 'meta', 'k', 'yes', 'y', 'force', 'verbose', 'path',\n ]);\n const sources: Record<string, number> = {};\n for (let i = 0; i < args.length; i++) {\n if (!args[i].startsWith('--')) continue;\n const name = args[i].slice(2);\n // --no-git, --no-code → set to 0\n if (name.startsWith('no-')) {\n sources[name.slice(3)] = 0;\n continue;\n }\n // --code 20, --git 5\n const next = args[i + 1];\n if (next !== undefined && /^\\d+$/.test(next) && !NON_SOURCE.has(name)) {\n sources[name] = parseInt(next, 10);\n i++;\n }\n }\n return sources;\n}\n\nexport async function cmdContext(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1];\n\n // brainbank context add <collection> <path> <description>\n if (sub === 'add') {\n const collection = pos[2];\n const path = pos[3];\n const desc = pos.slice(4).join(' ');\n\n if (!collection || !path || !desc) {\n console.log(c.red('Usage: brainbank context add <collection> <path> <description>'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.red('Docs plugin not loaded.')); process.exit(1); }\n docsPlugin.addContext(collection, path, desc);\n console.log(c.green(`✓ Context added: ${collection}:${path} → \"${desc}\"`));\n brain.close();\n return;\n }\n\n // brainbank context list\n if (sub === 'list') {\n const brain = await createBrain();\n await brain.initialize();\n const docsPlugin = findDocsPlugin(brain);\n if (!docsPlugin) { console.log(c.yellow(' Docs plugin not loaded.')); brain.close(); return; }\n const contexts = docsPlugin.listContexts();\n if (contexts.length === 0) {\n console.log(c.yellow(' No contexts configured.'));\n } else {\n console.log(c.bold('\\n━━━ Contexts ━━━\\n'));\n for (const ctx of contexts) {\n console.log(` ${c.cyan(ctx.collection)}:${ctx.path} → ${c.dim(ctx.context)}`);\n }\n }\n brain.close();\n return;\n }\n\n // brainbank context <task> — get formatted context\n const task = stripFlags(args).slice(1).join(' ');\n if (!task) {\n console.log(c.red('Usage: brainbank context <task description>'));\n console.log(c.dim(' brainbank context add <collection> <path> <description>'));\n console.log(c.dim(' brainbank context list'));\n process.exit(1);\n }\n\n const sources = parseContextFlags();\n const pathPrefix = getFlag('path');\n const ignorePaths = getFlagAll('ignore');\n const repo = getFlag('repo');\n\n // Parse BrainBankQL field flags\n const fields = parseFieldFlags();\n\n // Try HTTP server delegation first\n const serverResult = await tryServerContext({\n task,\n repo: repo ?? process.cwd(),\n sources: Object.keys(sources).length > 0 ? sources : undefined,\n pathPrefix,\n });\n\n if (serverResult !== null) {\n console.log(serverResult);\n return;\n }\n\n // Fall back to local\n const brain = await createBrain();\n const context = await brain.getContext(task, {\n sources: Object.keys(sources).length > 0 ? sources : undefined,\n pathPrefix,\n ignorePaths: ignorePaths.length > 0 ? ignorePaths : undefined,\n source: 'cli',\n fields: Object.keys(fields).length > 0 ? fields : undefined,\n });\n console.log(context);\n brain.close();\n}\n\n/** Parse BrainBankQL field flags: --lines, --symbols, --compact, --no-callTree, --callTree.depth=N, etc. */\nfunction parseFieldFlags(): Record<string, unknown> {\n const FIELD_BOOLEANS = new Set(['lines', 'symbols', 'compact', 'expander']);\n const FIELD_NEGATABLE = new Set(['callTree', 'imports']);\n const fields: Record<string, unknown> = {};\n\n for (let i = 0; i < args.length; i++) {\n if (!args[i].startsWith('--')) continue;\n const raw = args[i].slice(2);\n\n // --no-callTree, --no-imports → set to false\n if (raw.startsWith('no-')) {\n const name = raw.slice(3);\n if (FIELD_NEGATABLE.has(name)) {\n fields[name] = false;\n }\n continue;\n }\n\n // --callTree.depth=4 → { depth: 4 }\n const dotIdx = raw.indexOf('.');\n if (dotIdx > 0) {\n const fieldName = raw.slice(0, dotIdx);\n const rest = raw.slice(dotIdx + 1);\n const eqIdx = rest.indexOf('=');\n if (eqIdx > 0) {\n const key = rest.slice(0, eqIdx);\n const val = parseInt(rest.slice(eqIdx + 1), 10);\n if (!isNaN(val)) {\n fields[fieldName] = { [key]: val };\n }\n }\n continue;\n }\n\n // --lines, --symbols, --compact, --expander → true\n if (FIELD_BOOLEANS.has(raw)) {\n fields[raw] = true;\n }\n }\n\n return fields;\n}\n","/**\n * brainbank files <path|glob> [...paths] [--lines]\n *\n * Fetch full file contents from the index.\n * Use after `brainbank context` to view complete files identified by search.\n */\n\nimport { c, args, getFlag } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdFiles(): Promise<void> {\n // Collect positional args (file patterns) — skip 'files' command itself\n const patterns: string[] = [];\n const showLines = args.includes('--lines');\n\n for (let i = 1; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n // Skip --lines and --repo <value>\n if (args[i] === '--repo') {\n i++; // skip value\n }\n continue;\n }\n patterns.push(args[i]);\n }\n\n if (patterns.length === 0) {\n console.log(c.red('Usage: brainbank files <path|glob> [...paths] [--lines]'));\n console.log(c.dim(' Exact: brainbank files src/auth/login.ts'));\n console.log(c.dim(' Directory: brainbank files src/graph/'));\n console.log(c.dim(' Glob: brainbank files \"src/**/*.service.ts\"'));\n console.log(c.dim(' Fuzzy: brainbank files plugin.ts'));\n console.log(c.dim(' Lines: brainbank files src/plugin.ts --lines'));\n process.exit(1);\n }\n\n const brain = await createBrain();\n await brain.initialize();\n const results = brain.resolveFiles(patterns);\n\n if (results.length === 0) {\n console.log(c.yellow('No matching files found in the index.'));\n console.log(c.dim('Run `brainbank index` first to index your codebase.'));\n brain.close();\n return;\n }\n\n // Format output\n for (const r of results) {\n const meta = r.metadata as Record<string, unknown>;\n const startLine = (meta.startLine as number) ?? 1;\n\n console.log(c.bold(`\\n── ${r.filePath} ──\\n`));\n\n if (showLines) {\n const codeLines = r.content.split('\\n');\n const pad = String(startLine + codeLines.length - 1).length;\n for (let i = 0; i < codeLines.length; i++) {\n const lineNum = c.dim(`${String(startLine + i).padStart(pad)}|`);\n console.log(`${lineNum} ${codeLines[i]}`);\n }\n } else {\n console.log(r.content);\n }\n }\n\n console.log(c.dim(`\\n${results.length} file(s) resolved.`));\n brain.close();\n}\n","/** brainbank stats — Show index statistics. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\n/** Convert camelCase/snake_case stat keys to human-readable labels. */\nfunction formatStatKey(key: string): string {\n return key\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase())\n .padEnd(16);\n}\n\nexport async function cmdStats(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n const s = brain.stats();\n\n console.log(c.bold('\\n━━━ BrainBank Stats ━━━\\n'));\n console.log(` ${c.cyan('Plugins')}: ${brain.plugins.join(', ')}\\n`);\n\n for (const [name, pluginStats] of Object.entries(s)) {\n if (!pluginStats) continue;\n console.log(` ${c.cyan(name)}`);\n for (const [key, value] of Object.entries(pluginStats)) {\n console.log(` ${formatStatKey(key)}${value}`);\n }\n console.log('');\n }\n\n const kvNames = brain.listCollectionNames();\n if (kvNames.length > 0) {\n console.log(` ${c.cyan('KV Collections')}`);\n for (const name of kvNames) {\n const coll = brain.collection(name);\n console.log(` ${name}: ${coll.count()} items`);\n }\n console.log('');\n }\n\n brain.close();\n}\n","/** brainbank reembed — Re-embed all vectors. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdReembed(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n console.log(c.bold('\\n━━━ BrainBank Re-embed ━━━\\n'));\n console.log(c.dim(' Regenerating vectors with current embedding provider...'));\n console.log(c.dim(' Text, FTS, and metadata remain unchanged.\\n'));\n\n const result = await brain.reembed({\n onProgress: (table: string, current: number, total: number) => {\n process.stdout.write(`\\r ${c.cyan(table.padEnd(8))} ${current}/${total}`);\n },\n });\n\n console.log('\\n');\n for (const [name, count] of Object.entries(result.counts)) {\n if (count > 0) {\n const label = name.charAt(0).toUpperCase() + name.slice(1);\n console.log(` ${c.green('✓')} ${label.padEnd(8)} ${count} vectors`);\n }\n }\n console.log(`\\n ${c.bold('Total')}: ${result.total} vectors regenerated\\n`);\n\n brain.close();\n}\n","/** brainbank watch — Watch for file changes. */\n\nimport { c } from '@/cli/utils.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\nimport { loadConfig } from '@/cli/factory/config-loader.ts';\n\nexport async function cmdWatch(): Promise<void> {\n const brain = await createBrain();\n await brain.initialize();\n\n // Read ignore patterns from config (code.ignore + top-level ignore)\n const config = await loadConfig(brain.config.repoPath);\n const codeIgnore = (config?.code as Record<string, unknown> | undefined)?.ignore as string[] ?? [];\n\n console.log(c.bold('\\n━━━ BrainBank Watch ━━━\\n'));\n console.log(c.dim(` Watching ${brain.config.repoPath} for changes...`));\n if (codeIgnore.length > 0) {\n console.log(c.dim(` Ignoring: ${codeIgnore.join(', ')}`));\n }\n console.log(c.dim(' Press Ctrl+C to stop.\\n'));\n\n const watcher = brain.watch({\n debounceMs: 2000,\n ignore: codeIgnore,\n onIndex: (sourceId: string, pluginName: string) => {\n const ts = new Date().toLocaleTimeString();\n console.log(` ${c.dim(ts)} ${c.green('✓')} ${c.cyan(pluginName)}: ${sourceId}`);\n },\n onError: (err: Error) => {\n console.error(` ${c.red('✗')} ${err.message}`);\n },\n });\n\n process.on('SIGINT', () => {\n console.log(c.dim('\\n Stopping watcher...'));\n watcher.close();\n brain.close();\n process.exit(0);\n });\n\n await new Promise(() => {});\n}\n\n","/** brainbank mcp — Start MCP server (stdio). Requires @brainbank/mcp. */\n\nimport { c } from '@/cli/utils.ts';\n\nexport async function cmdMcp(): Promise<void> {\n try {\n await import('@brainbank/mcp');\n } catch {\n console.error(c.red('Error: @brainbank/mcp is not installed.'));\n console.error(c.dim(' Install: npm i @brainbank/mcp'));\n process.exit(1);\n }\n}\n","/**\n * brainbank daemon — HTTP daemon for CLI delegation.\n *\n * brainbank daemon → Start foreground\n * brainbank daemon start → Start background (fork + PID file)\n * brainbank daemon stop → Stop background daemon\n * brainbank daemon restart → Stop + start\n */\n\nimport { c, args, getFlag, stripFlags } from '@/cli/utils.ts';\nimport { isServerRunning, removePid, DEFAULT_PORT } from '@/services/daemon.ts';\nimport { createBrain } from '@/cli/factory/index.ts';\n\nexport async function cmdDaemon(): Promise<void> {\n const pos = stripFlags(args);\n const sub = pos[1]; // start | stop | undefined\n\n if (sub === 'stop') return stopDaemon();\n if (sub === 'restart') { stopDaemon(); return forkDaemon(); }\n if (sub === 'start') return forkDaemon();\n return startForeground();\n}\n\n// ── Foreground ──────────────────────────────────\n\nasync function startForeground(): Promise<void> {\n const port = parseInt(getFlag('port') ?? String(DEFAULT_PORT), 10);\n const { HttpServer } = await import('@/services/http-server.ts');\n\n const server = new HttpServer({\n port,\n factory: async (repoPath: string) => {\n const brain = await createBrain(repoPath);\n await brain.initialize();\n return brain;\n },\n onError: (repo, err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(c.red(` Pool error [${repo}]: ${msg}`));\n },\n onLog: (msg) => console.log(c.dim(` ${msg}`)),\n });\n\n console.log(c.bold('\\n━━━ BrainBank HTTP Daemon ━━━\\n'));\n\n await server.start();\n\n console.log(c.dim(` Port: ${port}`));\n console.log(c.dim(' Press Ctrl+C to stop.\\n'));\n\n const shutdown = () => {\n console.log(c.dim('\\n Shutting down...'));\n server.close();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await new Promise(() => {});\n}\n\n// ── Background ──────────────────────────────────\n\nasync function forkDaemon(): Promise<void> {\n const port = parseInt(getFlag('port') ?? String(DEFAULT_PORT), 10);\n const { fork } = await import('node:child_process');\n\n const existing = isServerRunning();\n if (existing) {\n console.log(c.yellow(` Daemon already running (PID ${existing.pid}, port ${existing.port})`));\n return;\n }\n\n const child = fork(process.argv[1], ['daemon', '--port', String(port)], {\n detached: true,\n stdio: 'ignore',\n });\n\n child.unref();\n\n console.log(c.green(` ✓ Daemon started (PID ${child.pid}, port ${port})`));\n console.log(c.dim(' Stop with: brainbank daemon stop'));\n}\n\nfunction stopDaemon(): void {\n const info = isServerRunning();\n if (!info) {\n console.log(c.yellow(' No daemon running.'));\n return;\n }\n\n try {\n process.kill(info.pid, 'SIGTERM');\n removePid();\n console.log(c.green(` ✓ Daemon stopped (PID ${info.pid})`));\n } catch {\n removePid();\n console.log(c.yellow(` PID ${info.pid} not found. Cleaned up stale PID file.`));\n }\n}\n","/**\n * Status Command — Show BrainBank server status.\n *\n * Usage: brainbank status\n */\n\nimport { c } from '@/cli/utils.ts';\nimport { serverHealth } from '@/cli/server-client.ts';\nimport { isServerRunning } from '@/services/daemon.ts';\n\nfunction formatUptime(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return remainMinutes > 0 ? `${hours}h ${remainMinutes}m` : `${hours}h`;\n}\n\nexport async function cmdStatus(): Promise<void> {\n const info = isServerRunning();\n\n if (!info) {\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.yellow('stopped')}\\n`);\n console.log(c.dim(' Start with: brainbank daemon'));\n console.log('');\n return;\n }\n\n // Try to get detailed health from the server\n const health = await serverHealth();\n\n if (health) {\n const uptime = formatUptime(health.uptime);\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.green('running')}`);\n console.log(` ${c.dim('PID:')} ${health.pid}`);\n console.log(` ${c.dim('Port:')} ${health.port}`);\n console.log(` ${c.dim('Uptime:')} ${uptime}`);\n console.log(` ${c.dim('Workspaces:')} ${health.workspaces}`);\n console.log('');\n } else {\n // PID file exists but server not responding\n console.log(`\\n ${c.dim('HTTP Server:')} ${c.yellow('stale')} (PID ${info.pid} not responding)`);\n console.log(c.dim(' The PID file may be stale. Restart with: brainbank daemon'));\n console.log('');\n }\n}\n","/** brainbank help — Show CLI usage. */\n\nimport { c } from '@/cli/utils.ts';\n\nexport function showHelp(): void {\n console.log(c.bold('\\n━━━ BrainBank — Semantic Knowledge Bank ━━━\\n'));\n console.log(c.bold('Indexing:'));\n console.log(` ${c.cyan('index')} ${c.dim('(i)')} [path] Index code + git history`);\n console.log(` ${c.cyan('collection add')} <path> --name Add a document collection`);\n console.log(` ${c.cyan('collection list')} List collections`);\n console.log(` ${c.cyan('collection remove')} <name> Remove a collection`);\n console.log(` ${c.cyan('docs')} [--collection <name>] Index document collections`);\n console.log('');\n console.log(c.bold('Search:'));\n console.log(` ${c.cyan('search')} <query> Semantic search (vector)`);\n console.log(` ${c.cyan('hsearch')} <query> Hybrid search (${c.bold('best quality')})`);\n console.log(` ${c.cyan('ksearch')} <query> Keyword search (BM25, instant)`);\n console.log(` ${c.cyan('dsearch')} <query> Document search`);\n console.log(c.dim(' All search commands accept --<source> <n> to filter by source'));\n console.log('');\n console.log(c.bold('Context:'));\n console.log(` ${c.cyan('context')} <task> Get formatted context for a task`);\n console.log(` ${c.cyan('context add')} <col> <path> <desc> Add context metadata`);\n console.log(` ${c.cyan('context list')} List all context metadata`);\n console.log(` ${c.cyan('files')} <path|glob> [...] [--lines] View full indexed files directly`);\n console.log('');\n console.log(c.bold('KV Store:'));\n console.log(` ${c.cyan('kv add')} <coll> <content> Add item to a collection`);\n console.log(` ${c.cyan('kv search')} <coll> <query> Search a collection`);\n console.log(` ${c.cyan('kv list')} [coll] List collections or items`);\n console.log(` ${c.cyan('kv trim')} <coll> --keep <n> Keep only N most recent`);\n console.log(` ${c.cyan('kv clear')} <coll> Clear all items`);\n console.log('');\n console.log(c.bold('Utility:'));\n console.log(` ${c.cyan('stats')} Show index statistics`);\n console.log(` ${c.cyan('reembed')} Re-embed all vectors`);\n console.log(` ${c.cyan('watch')} Watch files, auto-re-index`);\n console.log(` ${c.cyan('mcp')} Start MCP server (stdio)`);\n console.log(` ${c.cyan('mcp:export')} [target] Export MCP config (antigravity)`);\n console.log(` ${c.cyan('daemon')} Start HTTP daemon (foreground)`);\n console.log(` ${c.cyan('daemon start')} Start HTTP daemon (background)`);\n console.log(` ${c.cyan('daemon stop')} Stop background daemon`);\n console.log(` ${c.cyan('daemon restart')} Restart background daemon`);\n console.log(` ${c.cyan('status')} Show daemon status`);\n console.log(` ${c.cyan('--version')} ${c.dim('(-v)')} Show version`);\n console.log('');\n console.log(c.bold('Options:'));\n console.log(` ${c.dim('--repo <path>')} Repository path (default: .)`);\n console.log(` ${c.dim('--force')} Force re-index all files`);\n console.log(` ${c.dim('--depth <n>')} Git history depth (default: 500)`);\n console.log(` ${c.dim('--collection <name>')} Filter by collection`);\n console.log(` ${c.dim('--pattern <glob>')} Collection glob (default: **/*.md)`);\n console.log(` ${c.dim('--context <desc>')} Context description`);\n console.log(` ${c.dim('--<source> <n>')} Source filter: max results from <source> (0 = skip)`);\n console.log(` ${c.dim('--path <dir>')} Filter context results to files under this path prefix`);\n console.log(` ${c.dim('--ignore <globs>')} Ignore glob patterns for code indexing (comma-separated)`);\n console.log(` ${c.dim('--yes / -y')} Skip interactive prompt (auto-select all available)`);\n console.log(` ${c.dim('--reranker <name>')} Reranker to use (qwen3)`);\n console.log(` ${c.dim('--port <n>')} HTTP daemon port (default: 8181)`);\n console.log('');\n console.log(c.bold('Examples:'));\n console.log(c.dim(' brainbank index .'));\n console.log(c.dim(' brainbank index . --ignore \"sdk/**,vendor/**\"'));\n console.log(c.dim(' brainbank kv add errors \"Fixed null pointer in api.ts\"'));\n console.log(c.dim(' brainbank kv search errors \"null pointer\"'));\n console.log(c.dim(' brainbank kv list'));\n console.log(c.dim(' brainbank hsearch \"authentication middleware\"'));\n console.log(c.dim(' brainbank hsearch \"auth\" --code 0 --git 10 # git only'));\n console.log(c.dim(' brainbank search \"handler\" --git 0 # code only'));\n console.log(c.dim(' brainbank hsearch \"api\" --docs 10 --code 0 --git 0 # docs only'));\n console.log(c.dim(' brainbank context \"auth flow\" | pbcopy # → clipboard'));\n console.log(c.dim(' brainbank daemon start # background HTTP'));\n console.log(c.dim(' brainbank mcp # MCP stdio'));\n console.log(c.dim(' brainbank mcp:export antigravity # export MCP config'));\n}\n","#!/usr/bin/env node\n\n/**\n * BrainBank — CLI Entry Point\n *\n * Dispatcher that routes commands to their handler modules.\n */\n\nimport { args, c } from './utils.ts';\nimport { cmdIndex } from './commands/index.ts';\nimport { cmdCollection } from './commands/collection.ts';\nimport { cmdKv } from './commands/kv.ts';\nimport { cmdDocs, cmdDocSearch } from './commands/docs.ts';\nimport { cmdSearch, cmdHybridSearch, cmdKeywordSearch } from './commands/search.ts';\nimport { cmdContext } from './commands/context.ts';\nimport { cmdFiles } from './commands/files.ts';\nimport { cmdStats } from './commands/stats.ts';\nimport { cmdReembed } from './commands/reembed.ts';\nimport { cmdWatch } from './commands/watch.ts';\nimport { cmdMcp } from './commands/mcp.ts';\nimport { cmdMcpExport } from './commands/mcp-export.ts';\nimport { cmdDaemon } from './commands/daemon.ts';\nimport { cmdStatus } from './commands/status.ts';\nimport { showHelp } from './commands/help.ts';\nimport { VERSION } from '@/constants.ts';\n\nconst command = args[0];\n\nasync function main(): Promise<void> {\n switch (command) {\n case '--version':\n case '-v':\n console.log(`brainbank v${VERSION}`);\n break;\n case 'i':\n case 'index': return cmdIndex();\n case 'collection': return cmdCollection();\n case 'kv': return cmdKv();\n case 'docs': return cmdDocs();\n case 'dsearch': return cmdDocSearch();\n case 'search': return cmdSearch();\n case 'hsearch': return cmdHybridSearch();\n case 'ksearch': return cmdKeywordSearch();\n case 'context': return cmdContext();\n case 'files': return cmdFiles();\n case 'stats': return cmdStats();\n case 'reembed': return cmdReembed();\n case 'watch': return cmdWatch();\n case 'mcp': return cmdMcp();\n case 'mcp:export': return cmdMcpExport();\n case 'serve': return cmdMcp(); // backward compat\n case 'daemon': return cmdDaemon();\n case 'status': return cmdStatus();\n case 'help':\n case '--help':\n case '-h':\n showHelp();\n break;\n default:\n if (command) console.log(c.red(`Unknown command: ${command}\\n`));\n showHelp();\n process.exit(command ? 1 : 0);\n }\n}\n\nmain().catch(err => {\n console.error(c.red(`Error: ${err.message}`));\n if (process.env.BRAINBANK_DEBUG) console.error(err.stack);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","fs","path","path","brain","coll","path","resolve","path","brain","c"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brainbank",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "Pluggable semantic memory for AI agents — hybrid search (vector + BM25) in a single SQLite file. Built-in code, git, and docs indexers. Bring your own.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,7 @@ interface McpConfig {
|
|
|
41
41
|
* Build the brainbank MCP server config block.
|
|
42
42
|
* Resolves node binary, dist/cli.js path, and API keys.
|
|
43
43
|
*/
|
|
44
|
-
function buildBrainbankMcpBlock(config: ProjectConfig | null
|
|
44
|
+
function buildBrainbankMcpBlock(config: ProjectConfig | null): McpServerConfig {
|
|
45
45
|
const nodeBin = process.execPath;
|
|
46
46
|
|
|
47
47
|
// Resolve dist/cli.js from the global install location (node_prefix/lib/node_modules/brainbank/dist/cli.js)
|
|
@@ -62,9 +62,6 @@ function buildBrainbankMcpBlock(config: ProjectConfig | null, repoPath: string):
|
|
|
62
62
|
if (anthropicKey) env.ANTHROPIC_API_KEY = anthropicKey;
|
|
63
63
|
if (openaiKey) env.OPENAI_API_KEY = openaiKey;
|
|
64
64
|
|
|
65
|
-
// Inject repo path so the MCP server knows where the index lives
|
|
66
|
-
env.BRAINBANK_REPO = path.resolve(repoPath);
|
|
67
|
-
|
|
68
65
|
const block: McpServerConfig = {
|
|
69
66
|
command: nodeBin,
|
|
70
67
|
args: ['--disable-warning=ExperimentalWarning', resolvedCliJs, 'mcp'],
|
|
@@ -129,7 +126,7 @@ export async function autoExportMcp(repoPath: string): Promise<void> {
|
|
|
129
126
|
if (hasBrainbankMcpEntry(target.configPath)) return;
|
|
130
127
|
|
|
131
128
|
const config = await getConfig(repoPath);
|
|
132
|
-
const block = buildBrainbankMcpBlock(config
|
|
129
|
+
const block = buildBrainbankMcpBlock(config);
|
|
133
130
|
mergeAndWrite(target.configPath, block);
|
|
134
131
|
console.log(` ${c.green('✓')} Exported MCP config to ${c.dim(path.relative(process.env.HOME ?? '', target.configPath))}`);
|
|
135
132
|
}
|
|
@@ -200,11 +197,11 @@ function replaceGeminiSection(geminiPath: string): void {
|
|
|
200
197
|
fs.writeFileSync(geminiPath, before + section + after);
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
/** CLI command: brainbank mcp:export [target] */
|
|
200
|
+
/** CLI command: brainbank mcp:export [target] [--force] */
|
|
204
201
|
export async function cmdMcpExport(): Promise<void> {
|
|
205
202
|
const targetName = args[1] || getFlag('target') || 'antigravity';
|
|
206
203
|
const repoPath = getFlag('repo') || '.';
|
|
207
|
-
const
|
|
204
|
+
const force = args.includes('--force') || args.includes('-f');
|
|
208
205
|
|
|
209
206
|
const target = TARGETS[targetName];
|
|
210
207
|
if (!target) {
|
|
@@ -214,7 +211,7 @@ export async function cmdMcpExport(): Promise<void> {
|
|
|
214
211
|
}
|
|
215
212
|
|
|
216
213
|
const config = await getConfig(repoPath);
|
|
217
|
-
const block = buildBrainbankMcpBlock(config
|
|
214
|
+
const block = buildBrainbankMcpBlock(config);
|
|
218
215
|
|
|
219
216
|
console.log(c.bold(`\n━━━ MCP Export: ${target.label} ━━━\n`));
|
|
220
217
|
|
|
@@ -222,12 +219,13 @@ export async function cmdMcpExport(): Promise<void> {
|
|
|
222
219
|
const mcpExists = hasBrainbankMcpEntry(target.configPath);
|
|
223
220
|
let writeMcp = true;
|
|
224
221
|
|
|
225
|
-
if (mcpExists) {
|
|
222
|
+
if (mcpExists && !force) {
|
|
226
223
|
console.log(` ${c.yellow('●')} MCP config already has brainbank entry`);
|
|
227
224
|
const cliPath = block.args.find(a => !a.startsWith('--')) ?? block.args[0];
|
|
228
225
|
console.log(` ${c.dim(' New:')} ${block.command} ${cliPath}`);
|
|
229
226
|
const envKeys = block.env ? Object.keys(block.env) : [];
|
|
230
227
|
if (envKeys.length > 0) console.log(` ${c.dim(' Keys:')} ${envKeys.join(', ')}`);
|
|
228
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
231
229
|
writeMcp = await confirm({ message: 'Override existing brainbank MCP entry?', default: true });
|
|
232
230
|
}
|
|
233
231
|
|
|
@@ -242,22 +240,34 @@ export async function cmdMcpExport(): Promise<void> {
|
|
|
242
240
|
const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);
|
|
243
241
|
|
|
244
242
|
if (geminiHasSection) {
|
|
245
|
-
|
|
246
|
-
const override = await confirm({ message: 'Override existing BrainBank section?', default: false });
|
|
247
|
-
if (override) {
|
|
243
|
+
if (force) {
|
|
248
244
|
replaceGeminiSection(GLOBAL_GEMINI);
|
|
249
245
|
console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);
|
|
250
246
|
} else {
|
|
251
|
-
console.log(` ${c.
|
|
247
|
+
console.log(` ${c.yellow('●')} ~/.gemini/GEMINI.md already has BrainBank section`);
|
|
248
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
249
|
+
const override = await confirm({ message: 'Override existing BrainBank section?', default: false });
|
|
250
|
+
if (override) {
|
|
251
|
+
replaceGeminiSection(GLOBAL_GEMINI);
|
|
252
|
+
console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);
|
|
253
|
+
} else {
|
|
254
|
+
console.log(` ${c.dim('GEMINI.md — skipped')}`);
|
|
255
|
+
}
|
|
252
256
|
}
|
|
253
257
|
} else {
|
|
254
|
-
|
|
255
|
-
message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',
|
|
256
|
-
default: true,
|
|
257
|
-
});
|
|
258
|
-
if (addGemini) {
|
|
258
|
+
if (force) {
|
|
259
259
|
appendGeminiSection(GLOBAL_GEMINI);
|
|
260
260
|
console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);
|
|
261
|
+
} else {
|
|
262
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
263
|
+
const addGemini = await confirm({
|
|
264
|
+
message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',
|
|
265
|
+
default: true,
|
|
266
|
+
});
|
|
267
|
+
if (addGemini) {
|
|
268
|
+
appendGeminiSection(GLOBAL_GEMINI);
|
|
269
|
+
console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);
|
|
270
|
+
}
|
|
261
271
|
}
|
|
262
272
|
}
|
|
263
273
|
|