brainbank 0.9.5 → 0.9.7

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 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, repoPath) {
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, repoPath);
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
  }
@@ -117,24 +116,22 @@ function buildGeminiSection() {
117
116
 
118
117
  ## BrainBank \u2014 Code Intelligence
119
118
 
120
- When \`brainbank_context\` and \`brainbank_files\` MCP tools are available, **always use them instead of \`grep_search\` or \`list_dir\`**.
119
+ **\`brainbank_context\`** \u2014 semantic code discovery. Use it **only** when you need to understand functionality that spans multiple files (e.g. "how does auth work", "notification pipeline"). \`repo\` is **required**.
121
120
 
122
- **\`brainbank_context\`** \u2014 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 }\`.
121
+ **Do NOT use it for:** finding a specific string, variable, function name, or exact match \u2014 use \`grep_search\` for that. BrainBank is for *understanding context*, not for *locating text*.
123
122
 
124
- **\`brainbank_files\`** \u2014 read full indexed files (\`lines: true\` always). Only works with files tracked by the index \u2014 for \`.env\`, \`docker-compose.yml\`, etc. use \`view_file\`.
123
+ **Params:** \`compact: false\`, \`sources: { code: 25, docs: 0, git: 0 }\`. Only add \`docs\` when the user explicitly asks about documentation.
125
124
 
126
- **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 \u2014 fire separate queries.
127
-
128
- ### Output handling (critical)
125
+ ### Output handling \u2014 MANDATORY
129
126
 
130
127
  BrainBank may return results **inline** or save them to an **output file**:
131
128
 
132
129
  - **Inline:** read and proceed normally.
133
- - **File result** (saved to \`output.txt\`): show the path as a clickable link, ask user to paste, then **STOP and WAIT**:
130
+ - **File result** (saved to \`output.txt\`): you **MUST STOP IMMEDIATELY**. Show the path as a clickable link, ask the user to paste, then **DO NOT PROCEED**:
134
131
 
135
132
  \u{1F4CB} Output: [output.txt](file:///path/to/output.txt) \u2014 _"Could you paste the context output here?"_
136
133
 
137
- Do **NOT** read the file yourself. Wait for the paste before proceeding.
134
+ **NEVER** read the file yourself. **NEVER** continue working. Wait for the user to paste the content. This is not optional.
138
135
 
139
136
  ${BRAINBANK_SECTION_END}
140
137
  `;
@@ -170,7 +167,7 @@ __name(replaceGeminiSection, "replaceGeminiSection");
170
167
  async function cmdMcpExport() {
171
168
  const targetName = args[1] || getFlag("target") || "antigravity";
172
169
  const repoPath = getFlag("repo") || ".";
173
- const { confirm } = await import("@inquirer/prompts");
170
+ const force = args.includes("--force") || args.includes("-f");
174
171
  const target = TARGETS[targetName];
175
172
  if (!target) {
176
173
  console.error(c.red(`Unknown export target: ${targetName}`));
@@ -178,18 +175,19 @@ async function cmdMcpExport() {
178
175
  process.exit(1);
179
176
  }
180
177
  const config = await getConfig(repoPath);
181
- const block = buildBrainbankMcpBlock(config, repoPath);
178
+ const block = buildBrainbankMcpBlock(config);
182
179
  console.log(c.bold(`
183
180
  \u2501\u2501\u2501 MCP Export: ${target.label} \u2501\u2501\u2501
184
181
  `));
185
182
  const mcpExists = hasBrainbankMcpEntry(target.configPath);
186
183
  let writeMcp = true;
187
- if (mcpExists) {
184
+ if (mcpExists && !force) {
188
185
  console.log(` ${c.yellow("\u25CF")} MCP config already has brainbank entry`);
189
186
  const cliPath = block.args.find((a) => !a.startsWith("--")) ?? block.args[0];
190
187
  console.log(` ${c.dim(" New:")} ${block.command} ${cliPath}`);
191
188
  const envKeys = block.env ? Object.keys(block.env) : [];
192
189
  if (envKeys.length > 0) console.log(` ${c.dim(" Keys:")} ${envKeys.join(", ")}`);
190
+ const { confirm } = await import("@inquirer/prompts");
193
191
  writeMcp = await confirm({ message: "Override existing brainbank MCP entry?", default: true });
194
192
  }
195
193
  if (writeMcp) {
@@ -200,22 +198,34 @@ async function cmdMcpExport() {
200
198
  }
201
199
  const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);
202
200
  if (geminiHasSection) {
203
- console.log(` ${c.yellow("\u25CF")} ~/.gemini/GEMINI.md already has BrainBank section`);
204
- const override = await confirm({ message: "Override existing BrainBank section?", default: false });
205
- if (override) {
201
+ if (force) {
206
202
  replaceGeminiSection(GLOBAL_GEMINI);
207
203
  console.log(` ${c.green("\u2713")} Replaced BrainBank section in ${c.dim("~/.gemini/GEMINI.md")}`);
208
204
  } else {
209
- console.log(` ${c.dim("GEMINI.md \u2014 skipped")}`);
205
+ console.log(` ${c.yellow("\u25CF")} ~/.gemini/GEMINI.md already has BrainBank section`);
206
+ const { confirm } = await import("@inquirer/prompts");
207
+ const override = await confirm({ message: "Override existing BrainBank section?", default: false });
208
+ if (override) {
209
+ replaceGeminiSection(GLOBAL_GEMINI);
210
+ console.log(` ${c.green("\u2713")} Replaced BrainBank section in ${c.dim("~/.gemini/GEMINI.md")}`);
211
+ } else {
212
+ console.log(` ${c.dim("GEMINI.md \u2014 skipped")}`);
213
+ }
210
214
  }
211
215
  } else {
212
- const addGemini = await confirm({
213
- message: "Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)",
214
- default: true
215
- });
216
- if (addGemini) {
216
+ if (force) {
217
217
  appendGeminiSection(GLOBAL_GEMINI);
218
218
  console.log(` ${c.green("\u2713")} Added BrainBank section to ${c.dim("~/.gemini/GEMINI.md")}`);
219
+ } else {
220
+ const { confirm } = await import("@inquirer/prompts");
221
+ const addGemini = await confirm({
222
+ message: "Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)",
223
+ default: true
224
+ });
225
+ if (addGemini) {
226
+ appendGeminiSection(GLOBAL_GEMINI);
227
+ console.log(` ${c.green("\u2713")} Added BrainBank section to ${c.dim("~/.gemini/GEMINI.md")}`);
228
+ }
219
229
  }
220
230
  }
221
231
  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\n**\\`brainbank_context\\`** — semantic code discovery. Use it **only** when you need to understand functionality that spans multiple files (e.g. \"how does auth work\", \"notification pipeline\"). \\`repo\\` is **required**.\n\n**Do NOT use it for:** finding a specific string, variable, function name, or exact match — use \\`grep_search\\` for that. BrainBank is for *understanding context*, not for *locating text*.\n\n**Params:** \\`compact: false\\`, \\`sources: { code: 25, docs: 0, git: 0 }\\`. Only add \\`docs\\` when the user explicitly asks about documentation.\n\n### Output handling — MANDATORY\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\\`): you **MUST STOP IMMEDIATELY**. Show the path as a clickable link, ask the user to paste, then **DO NOT PROCEED**:\n\n 📋 Output: [output.txt](file:///path/to/output.txt) — _\"Could you paste the context output here?\"_\n\n **NEVER** read the file yourself. **NEVER** continue working. Wait for the user to paste the content. This is not optional.\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.5",
3
+ "version": "0.9.7",
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, repoPath: string): McpServerConfig {
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, repoPath);
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
  }
@@ -147,24 +144,22 @@ function buildGeminiSection(): string {
147
144
 
148
145
  ## BrainBank — Code Intelligence
149
146
 
150
- When \`brainbank_context\` and \`brainbank_files\` MCP tools are available, **always use them instead of \`grep_search\` or \`list_dir\`**.
151
-
152
- **\`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 }\`.
147
+ **\`brainbank_context\`** semantic code discovery. Use it **only** when you need to understand functionality that spans multiple files (e.g. "how does auth work", "notification pipeline"). \`repo\` is **required**.
153
148
 
154
- **\`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\`.
149
+ **Do NOT use it for:** finding a specific string, variable, function name, or exact match use \`grep_search\` for that. BrainBank is for *understanding context*, not for *locating text*.
155
150
 
156
- **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.
151
+ **Params:** \`compact: false\`, \`sources: { code: 25, docs: 0, git: 0 }\`. Only add \`docs\` when the user explicitly asks about documentation.
157
152
 
158
- ### Output handling (critical)
153
+ ### Output handling — MANDATORY
159
154
 
160
155
  BrainBank may return results **inline** or save them to an **output file**:
161
156
 
162
157
  - **Inline:** read and proceed normally.
163
- - **File result** (saved to \`output.txt\`): show the path as a clickable link, ask user to paste, then **STOP and WAIT**:
158
+ - **File result** (saved to \`output.txt\`): you **MUST STOP IMMEDIATELY**. Show the path as a clickable link, ask the user to paste, then **DO NOT PROCEED**:
164
159
 
165
160
  📋 Output: [output.txt](file:///path/to/output.txt) — _"Could you paste the context output here?"_
166
161
 
167
- Do **NOT** read the file yourself. Wait for the paste before proceeding.
162
+ **NEVER** read the file yourself. **NEVER** continue working. Wait for the user to paste the content. This is not optional.
168
163
 
169
164
  ${BRAINBANK_SECTION_END}
170
165
  `;
@@ -200,11 +195,11 @@ function replaceGeminiSection(geminiPath: string): void {
200
195
  fs.writeFileSync(geminiPath, before + section + after);
201
196
  }
202
197
 
203
- /** CLI command: brainbank mcp:export [target] */
198
+ /** CLI command: brainbank mcp:export [target] [--force] */
204
199
  export async function cmdMcpExport(): Promise<void> {
205
200
  const targetName = args[1] || getFlag('target') || 'antigravity';
206
201
  const repoPath = getFlag('repo') || '.';
207
- const { confirm } = await import('@inquirer/prompts');
202
+ const force = args.includes('--force') || args.includes('-f');
208
203
 
209
204
  const target = TARGETS[targetName];
210
205
  if (!target) {
@@ -214,7 +209,7 @@ export async function cmdMcpExport(): Promise<void> {
214
209
  }
215
210
 
216
211
  const config = await getConfig(repoPath);
217
- const block = buildBrainbankMcpBlock(config, repoPath);
212
+ const block = buildBrainbankMcpBlock(config);
218
213
 
219
214
  console.log(c.bold(`\n━━━ MCP Export: ${target.label} ━━━\n`));
220
215
 
@@ -222,12 +217,13 @@ export async function cmdMcpExport(): Promise<void> {
222
217
  const mcpExists = hasBrainbankMcpEntry(target.configPath);
223
218
  let writeMcp = true;
224
219
 
225
- if (mcpExists) {
220
+ if (mcpExists && !force) {
226
221
  console.log(` ${c.yellow('●')} MCP config already has brainbank entry`);
227
222
  const cliPath = block.args.find(a => !a.startsWith('--')) ?? block.args[0];
228
223
  console.log(` ${c.dim(' New:')} ${block.command} ${cliPath}`);
229
224
  const envKeys = block.env ? Object.keys(block.env) : [];
230
225
  if (envKeys.length > 0) console.log(` ${c.dim(' Keys:')} ${envKeys.join(', ')}`);
226
+ const { confirm } = await import('@inquirer/prompts');
231
227
  writeMcp = await confirm({ message: 'Override existing brainbank MCP entry?', default: true });
232
228
  }
233
229
 
@@ -242,22 +238,34 @@ export async function cmdMcpExport(): Promise<void> {
242
238
  const geminiHasSection = hasGeminiSection(GLOBAL_GEMINI);
243
239
 
244
240
  if (geminiHasSection) {
245
- console.log(` ${c.yellow('●')} ~/.gemini/GEMINI.md already has BrainBank section`);
246
- const override = await confirm({ message: 'Override existing BrainBank section?', default: false });
247
- if (override) {
241
+ if (force) {
248
242
  replaceGeminiSection(GLOBAL_GEMINI);
249
243
  console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);
250
244
  } else {
251
- console.log(` ${c.dim('GEMINI.md skipped')}`);
245
+ console.log(` ${c.yellow('●')} ~/.gemini/GEMINI.md already has BrainBank section`);
246
+ const { confirm } = await import('@inquirer/prompts');
247
+ const override = await confirm({ message: 'Override existing BrainBank section?', default: false });
248
+ if (override) {
249
+ replaceGeminiSection(GLOBAL_GEMINI);
250
+ console.log(` ${c.green('✓')} Replaced BrainBank section in ${c.dim('~/.gemini/GEMINI.md')}`);
251
+ } else {
252
+ console.log(` ${c.dim('GEMINI.md — skipped')}`);
253
+ }
252
254
  }
253
255
  } else {
254
- const addGemini = await confirm({
255
- message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',
256
- default: true,
257
- });
258
- if (addGemini) {
256
+ if (force) {
259
257
  appendGeminiSection(GLOBAL_GEMINI);
260
258
  console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);
259
+ } else {
260
+ const { confirm } = await import('@inquirer/prompts');
261
+ const addGemini = await confirm({
262
+ message: 'Add BrainBank instructions to ~/.gemini/GEMINI.md? (teaches AI tools how to use BrainBank)',
263
+ default: true,
264
+ });
265
+ if (addGemini) {
266
+ appendGeminiSection(GLOBAL_GEMINI);
267
+ console.log(` ${c.green('✓')} Added BrainBank section to ${c.dim('~/.gemini/GEMINI.md')}`);
268
+ }
261
269
  }
262
270
  }
263
271