bluera-knowledge 0.36.0 → 0.37.1
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/bun.lock +27 -0
- package/dist/{chunk-L2SC6J4K.js → chunk-724FNI27.js} +466 -171
- package/dist/chunk-724FNI27.js.map +1 -0
- package/dist/{chunk-MQQ46BST.js → chunk-F6DGSS2N.js} +2 -2
- package/dist/{chunk-DNGE7FZ4.js → chunk-VB5V4RC7.js} +1387 -42
- package/dist/chunk-VB5V4RC7.js.map +1 -0
- package/dist/index.js +2153 -17
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +37 -3
- package/dist/mcp/server.js +2 -2
- package/dist/workers/background-worker-cli.js +2 -2
- package/hooks/check-ready.sh +17 -7
- package/hooks/lib/store_summary.py +111 -0
- package/hooks/posttooluse-bk-reminder.py +33 -6
- package/hooks/userpromptsubmit-bk-nudge.py +25 -5
- package/package.json +3 -1
- package/scripts/eval-candidates.sh +235 -0
- package/scripts/launch-ui.sh +20 -0
- package/scripts/preview-ui.ts +207 -0
- package/skills/advanced-workflows/references/combining-workflows.md +17 -0
- package/skills/advanced-workflows/references/error-recovery.md +44 -0
- package/skills/advanced-workflows/references/handling-large-results.md +48 -0
- package/skills/advanced-workflows/references/multi-store-search.md +42 -0
- package/skills/search/statusline.md +75 -0
- package/skills/store-lifecycle/references/failure-recovery.md +80 -0
- package/skills/store-lifecycle/references/indexing-strategies.md +67 -0
- package/skills/store-lifecycle/references/job-monitoring.md +72 -0
- package/skills/store-lifecycle/references/lifecycle-checklist.md +20 -0
- package/skills/store-lifecycle/references/storage-management.md +43 -0
- package/skills/ui/SKILL.md +27 -0
- package/dist/chunk-DNGE7FZ4.js.map +0 -1
- package/dist/chunk-L2SC6J4K.js.map +0 -1
- /package/dist/{chunk-MQQ46BST.js.map → chunk-F6DGSS2N.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/crawl.ts","../src/cli/commands/index-cmd.ts","../src/cli/commands/mcp.ts","../src/cli/commands/plugin-api.ts","../src/plugin/commands.ts","../src/analysis/dependency-usage-analyzer.ts","../src/analysis/repo-url-resolver.ts","../src/cli/commands/search.ts","../src/cli/commands/serve.ts","../src/server/app.ts","../src/cli/commands/setup.ts","../src/defaults/repos.ts","../src/cli/commands/store.ts","../src/cli/commands/sync.ts","../src/cli/program.ts","../src/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Command } from 'commander';\nimport ora, { type Ora } from 'ora';\nimport {\n getCrawlStrategy,\n IntelligentCrawler,\n type CrawlProgress,\n} from '../../crawl/intelligent-crawler.js';\nimport { ChunkingService } from '../../services/chunking.service.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { classifyWebContentType } from '../../services/index.service.js';\nimport { createDocumentId } from '../../types/brands.js';\nimport type { Document } from '../../types/document.js';\nimport type { WebStore } from '../../types/store.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createCrawlCommand(getOptions: () => GlobalOptions): Command {\n return new Command('crawl')\n .description('Crawl web pages with natural language control and index into store')\n .argument('<url>', 'URL to crawl')\n .argument('<store>', 'Target web store to add crawled content to')\n .option(\n '--crawl <instruction>',\n 'Natural language instruction for what to crawl (e.g., \"all Getting Started pages\")'\n )\n .option(\n '--extract <instruction>',\n 'Natural language instruction for what to extract (e.g., \"extract API references\")'\n )\n .option('--max-pages <number>', 'Maximum number of pages to crawl', '50')\n .option('--fast', 'Use fast axios-only mode (may fail on JavaScript-heavy sites)')\n .allowUnknownOption() // Allow --store= to be parsed so we can show helpful error\n .action(\n async (\n url: string,\n storeIdOrName: string,\n cmdOptions: {\n crawl?: string;\n extract?: string;\n maxPages: string;\n fast?: boolean;\n }\n ) => {\n // Detect common mistake: using --store= instead of positional argument\n const storeArg = process.argv.find((arg) => arg.startsWith('--store'));\n if (storeArg !== undefined) {\n const storeName = storeArg.includes('=') ? storeArg.split('=')[1] : 'NAME';\n const storeNameDisplay =\n storeName !== undefined && storeName !== '' ? storeName : 'my-store';\n console.error(`\nError: Store name should be a positional argument, not an option.\n\n WRONG: crawl ${url} ${storeArg}\n RIGHT: crawl ${url} ${storeNameDisplay}\n\nExample: bluera-knowledge crawl https://docs.example.com my-docs\n`);\n process.exitCode = 1;\n return;\n }\n\n const globalOpts = getOptions();\n const useHeadless = !(cmdOptions.fast ?? false);\n\n // IMPORTANT: Get crawl strategy BEFORE initializing lancedb services.\n // LanceDB's native Rust code is not fork-safe. Spawning Claude CLI after\n // lancedb is loaded corrupts the mutex state, causing crashes.\n const crawlInstruction = cmdOptions.crawl ?? 'crawl all pages linked from this URL';\n\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Crawling ${url}`);\n console.log('Analyzing page structure with Claude...');\n }\n const preComputedStrategy = await getCrawlStrategy(url, crawlInstruction, useHeadless);\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(\n `Claude identified ${String(preComputedStrategy.urls.length)} URLs: ${preComputedStrategy.reasoning}`\n );\n }\n\n // Now safe to initialize lancedb services\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n // Look up or auto-create web store\n let store: WebStore;\n let storeCreated = false;\n const existingStore = await services.store.getByIdOrName(storeIdOrName);\n\n if (!existingStore) {\n // Auto-create web store\n const result = await services.store.create({\n name: storeIdOrName,\n type: 'web',\n url,\n });\n if (!result.success) {\n await destroyServices(services);\n throw new Error(`Failed to create store: ${result.error.message}`);\n }\n // Type narrowing: success check above ensures result.data is Store\n // We know it's a WebStore because we created it with type: 'web'\n const createdStore = result.data;\n if (createdStore.type !== 'web') {\n throw new Error('Unexpected store type after creation');\n }\n store = createdStore;\n storeCreated = true;\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Created web store: ${store.name}`);\n }\n } else if (existingStore.type !== 'web') {\n await destroyServices(services);\n throw new Error(\n `Store \"${storeIdOrName}\" exists but is not a web store (type: ${existingStore.type})`\n );\n } else {\n store = existingStore;\n }\n\n const maxPages = parseInt(cmdOptions.maxPages, 10);\n if (Number.isNaN(maxPages)) {\n throw new Error(\n `Invalid value for --max-pages: \"${cmdOptions.maxPages}\" is not a valid integer`\n );\n }\n\n // Use spinner in interactive mode\n const isInteractive =\n process.stdout.isTTY && globalOpts.quiet !== true && globalOpts.format !== 'json';\n let spinner: Ora | undefined;\n\n if (isInteractive) {\n spinner = ora(`Crawling ${url} (intelligent mode)`).start();\n } else if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Crawling ${url}`);\n }\n\n const appConfig = await services.config.load();\n const crawler = new IntelligentCrawler(appConfig.crawl);\n // Use web preset for larger prose-friendly chunks\n const webChunker = ChunkingService.forContentType('web');\n let pagesIndexed = 0;\n let chunksCreated = 0;\n let exitCode = 0;\n\n // Listen for progress events\n crawler.on('progress', (progress: CrawlProgress) => {\n if (spinner) {\n if (progress.type === 'strategy') {\n spinner.text = progress.message ?? 'Analyzing crawl strategy...';\n } else if (progress.type === 'page') {\n const url = progress.currentUrl ?? 'unknown';\n spinner.text = `Crawling ${String(progress.pagesVisited + 1)}/${String(maxPages)} - ${url}`;\n } else if (progress.type === 'extraction') {\n const url = progress.currentUrl ?? 'unknown';\n spinner.text = `Extracting from ${url}...`;\n } else if (progress.type === 'error' && progress.message !== undefined) {\n spinner.warn(progress.message);\n }\n }\n });\n\n try {\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const docs: Document[] = [];\n\n // Crawl pages using IntelligentCrawler\n for await (const result of crawler.crawl(url, {\n crawlInstruction,\n ...(cmdOptions.extract !== undefined && { extractInstruction: cmdOptions.extract }),\n maxPages,\n useHeadless,\n preComputedStrategy,\n })) {\n // Use extracted content if available, otherwise markdown\n const contentToProcess = result.extracted ?? result.markdown;\n\n // Chunk the content using markdown-aware chunking (web content is converted to markdown)\n const chunks = webChunker.chunk(contentToProcess, `${result.url}.md`);\n const fileType = classifyWebContentType(result.url, result.title);\n const urlHash = createHash('md5').update(result.url).digest('hex');\n\n for (const chunk of chunks) {\n const chunkId =\n chunks.length > 1\n ? `${store.id}-${urlHash}-${String(chunk.chunkIndex)}`\n : `${store.id}-${urlHash}`;\n const vector = await services.embeddings.embedDocument(chunk.content);\n\n docs.push({\n id: createDocumentId(chunkId),\n content: chunk.content,\n vector,\n metadata: {\n type: chunks.length > 1 ? 'chunk' : 'web',\n storeId: store.id,\n url: result.url,\n title: result.title,\n extracted: result.extracted !== undefined,\n depth: result.depth,\n indexedAt: new Date().toISOString(),\n fileType,\n chunkIndex: chunk.chunkIndex,\n totalChunks: chunk.totalChunks,\n sectionHeader: chunk.sectionHeader,\n },\n });\n chunksCreated++;\n }\n\n pagesIndexed++;\n }\n\n // Index all documents\n if (docs.length > 0) {\n if (spinner) {\n spinner.text = 'Indexing documents...';\n }\n // Clear existing documents to prevent duplicates on re-crawl\n await services.lance.clearAllDocuments(store.id);\n await services.lance.addDocuments(store.id, docs);\n // Create FTS index for full-text search\n await services.lance.createFtsIndex(store.id);\n }\n\n const crawlResult = {\n success: true,\n store: store.name,\n storeCreated,\n url,\n pagesCrawled: pagesIndexed,\n chunksCreated,\n mode: 'intelligent',\n hadCrawlInstruction: cmdOptions.crawl !== undefined,\n hadExtractInstruction: cmdOptions.extract !== undefined,\n };\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(crawlResult, null, 2));\n } else if (spinner !== undefined) {\n spinner.succeed(\n `Crawled ${String(pagesIndexed)} pages, indexed ${String(chunksCreated)} chunks`\n );\n } else if (globalOpts.quiet !== true) {\n console.log(\n `Crawled ${String(pagesIndexed)} pages, indexed ${String(chunksCreated)} chunks`\n );\n }\n } catch (error) {\n const message = `Crawl failed: ${error instanceof Error ? error.message : String(error)}`;\n if (spinner) {\n spinner.fail(message);\n } else {\n console.error(`Error: ${message}`);\n }\n exitCode = 6;\n } finally {\n await crawler.stop();\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Using process.exitCode avoids mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n}\n","import { Command } from 'commander';\nimport ora, { type Ora } from 'ora';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { JobService } from '../../services/job.service.js';\nimport { validateStoreModelCompatibility } from '../../utils/model-validation.js';\nimport { spawnBackgroundWorker } from '../../workers/spawn-worker.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createIndexCommand(getOptions: () => GlobalOptions): Command {\n const index = new Command('index')\n .description('Scan store files, chunk text, generate embeddings, save to LanceDB')\n .argument('<store>', 'Store ID or name')\n .option('--force', 'Re-index all files even if unchanged')\n .action(async (storeIdOrName: string, options: { force?: boolean }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n indexLogic: {\n const store = await services.store.getByIdOrName(storeIdOrName);\n\n if (store === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n\n break indexLogic;\n }\n\n // Web stores need to be re-crawled, not re-indexed\n // Route to background crawl job\n if (store.type === 'web') {\n const dataDir = services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n const job = jobService.createJob({\n type: 'crawl',\n details: {\n storeName: store.name,\n storeId: store.id,\n url: store.url,\n maxPages: store.maxPages,\n crawlInstruction: store.crawlInstructions,\n extractInstruction: store.extractInstructions,\n phase: 'crawling',\n phaseStep: 1,\n phaseTotalSteps: 2,\n },\n message: `Re-crawling ${store.name}...`,\n });\n spawnBackgroundWorker(job.id, dataDir);\n\n if (globalOpts.format === 'json') {\n console.log(\n JSON.stringify(\n {\n store: { id: store.id, name: store.name, type: store.type },\n job: { id: job.id, status: job.status },\n message: `Re-crawl queued (Job ID: ${job.id})`,\n },\n null,\n 2\n )\n );\n } else if (globalOpts.quiet !== true) {\n console.log(`Re-crawl job queued for ${store.name} (Job ID: ${job.id})`);\n console.log(`Check status: bluera-knowledge jobs status ${job.id}`);\n }\n\n break indexLogic;\n }\n\n // Use spinner in interactive mode (not quiet, not json output)\n const isInteractive =\n process.stdout.isTTY && globalOpts.quiet !== true && globalOpts.format !== 'json';\n let spinner: Ora | undefined;\n\n if (isInteractive) {\n spinner = ora(`Indexing store: ${store.name}`).start();\n } else if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Indexing store: ${store.name}`);\n }\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n\n // Validate model compatibility for incremental indexing (not --force)\n // Full reindex is always allowed since it replaces all data\n if (options.force !== true) {\n const currentModelId = services.store.getCurrentModelId();\n validateStoreModelCompatibility(store, { currentModelId });\n }\n\n // Use full re-index with --force, otherwise incremental (default)\n const progressCallback = (event: {\n type: string;\n current: number;\n total: number;\n message: string;\n }): void => {\n if (event.type === 'progress') {\n if (spinner) {\n spinner.text = `Indexing: ${String(event.current)}/${String(event.total)} files - ${event.message}`;\n }\n }\n };\n\n const result =\n options.force === true\n ? await services.index.indexStore(store, progressCallback)\n : await services.index.indexStoreIncremental(store, progressCallback);\n\n if (result.success) {\n // Upgrade schema v1 stores to v2 after successful reindex\n // This adds modelId so the store becomes searchable\n if (!store.modelId) {\n await services.store.upgradeStoreSchema(store.id);\n }\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result.data, null, 2));\n } else {\n const message = `Indexed ${String(result.data.filesIndexed)} documents, ${String(result.data.chunksCreated)} chunks in ${String(result.data.timeMs)}ms`;\n if (spinner !== undefined) {\n spinner.succeed(message);\n } else if (globalOpts.quiet !== true) {\n console.log(message);\n }\n }\n } else {\n const message = `Error: ${result.error.message}`;\n if (spinner !== undefined) {\n spinner.fail(message);\n } else {\n console.error(message);\n }\n exitCode = 4;\n\n break indexLogic;\n }\n }\n } finally {\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Using process.exitCode avoids mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n index\n .command('watch <store>')\n .description('Watch store directory; re-index when files change')\n .option(\n '--debounce <ms>',\n 'Wait N ms after last change before re-indexing (default: 1000)',\n '1000'\n )\n .action(async (storeIdOrName: string, options: { debounce: string }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n const store = await services.store.getByIdOrName(storeIdOrName);\n if (store === undefined || (store.type !== 'file' && store.type !== 'repo')) {\n console.error(`Error: File/repo store not found: ${storeIdOrName}`);\n // Cleanup services before exiting (using exitCode avoids mutex crashes)\n await destroyServices(services);\n process.exitCode = 3;\n return;\n }\n\n const appConfig = await services.config.load();\n const { WatchService } = await import('../../services/watch.service.js');\n const watchService = new WatchService(services.index, services.lance, services.embeddings, {\n ignorePatterns: appConfig.indexing.ignorePatterns,\n currentModelId: services.store.getCurrentModelId(),\n });\n\n const debounceMs = parseInt(options.debounce, 10);\n if (Number.isNaN(debounceMs)) {\n throw new Error(\n `Invalid value for --debounce: \"${options.debounce}\" is not a valid integer`\n );\n }\n\n if (globalOpts.quiet !== true) {\n console.log(`Watching ${store.name} for changes...`);\n }\n await watchService.watch(\n store,\n debounceMs,\n () => {\n if (globalOpts.quiet !== true) {\n console.log(`Re-indexed ${store.name}`);\n }\n },\n (error: Error) => {\n console.error(`Watch error: ${error.message}`);\n }\n );\n\n // Keep process alive\n process.on('SIGINT', () => {\n void (async (): Promise<void> => {\n await watchService.unwatchAll();\n await destroyServices(services);\n process.exit(0);\n })().catch((err: unknown) => {\n console.error('Shutdown error:', err);\n process.exit(1);\n });\n });\n });\n\n return index;\n}\n","import { Command } from 'commander';\nimport { runMCPServer } from '../../mcp/server.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createMCPCommand(getOptions: () => GlobalOptions): Command {\n const mcp = new Command('mcp')\n .description('Start MCP (Model Context Protocol) server for AI agent integration')\n .action(async () => {\n const opts = getOptions();\n\n await runMCPServer({\n dataDir: opts.dataDir,\n config: opts.config,\n projectRoot: opts.projectRoot,\n });\n });\n\n return mcp;\n}\n","import { Command } from 'commander';\nimport {\n handleAddRepo,\n handleAddFolder,\n handleStores,\n handleSuggest,\n} from '../../plugin/commands.js';\nimport type { GlobalOptions } from '../program.js';\n\n/**\n * CLI commands that mirror the plugin API for consistency.\n * These commands provide a simpler interface that matches the plugin commands.\n */\n\nexport function createAddRepoCommand(getOptions: () => GlobalOptions): Command {\n return new Command('add-repo')\n .description('Clone and index a library source repository')\n .argument('<url>', 'Git repository URL')\n .option('--name <name>', 'Store name (defaults to repo name)')\n .option('--branch <branch>', 'Git branch to clone')\n .action(async (url: string, options: { name?: string; branch?: string }) => {\n const globalOpts = getOptions();\n await handleAddRepo(\n { url, ...options },\n {\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n }\n );\n });\n}\n\nexport function createAddFolderCommand(getOptions: () => GlobalOptions): Command {\n return new Command('add-folder')\n .description('Index a local folder of reference material')\n .argument('<path>', 'Folder path to index')\n .option('--name <name>', 'Store name (defaults to folder name)')\n .action(async (path: string, options: { name?: string }) => {\n const globalOpts = getOptions();\n await handleAddFolder(\n { path, ...options },\n {\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n }\n );\n });\n}\n\nexport function createStoresCommand(getOptions: () => GlobalOptions): Command {\n return new Command('stores').description('List all indexed library stores').action(async () => {\n const globalOpts = getOptions();\n await handleStores({\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n });\n });\n}\n\nexport function createSuggestCommand(getOptions: () => GlobalOptions): Command {\n return new Command('suggest')\n .description('Suggest important dependencies to add to knowledge stores')\n .action(async () => {\n const globalOpts = getOptions();\n await handleSuggest({\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n });\n });\n}\n","import { execSync } from 'node:child_process';\nimport ora from 'ora';\nimport { extractRepoName } from './git-clone.js';\nimport { DependencyUsageAnalyzer } from '../analysis/dependency-usage-analyzer.js';\nimport { RepoUrlResolver } from '../analysis/repo-url-resolver.js';\nimport { createLogger } from '../logging/index.js';\nimport { createServices, destroyServices } from '../services/index.js';\nimport type { PackageUsage } from '../analysis/dependency-usage-analyzer.js';\n\nconst logger = createLogger('plugin-commands');\n\n/** Safely extract a string field from an unknown parsed JSON value. */\nfunction extractStringField(obj: unknown, key: string): string | undefined {\n if (typeof obj !== 'object' || obj === null || !(key in obj)) return undefined;\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) return undefined;\n const value: unknown = descriptor.value;\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Options passed from CLI global options to plugin command handlers.\n */\nexport interface CommandOptions {\n config?: string | undefined;\n dataDir?: string | undefined;\n projectRoot?: string | undefined;\n format?: 'json' | 'table' | 'plain' | undefined;\n quiet?: boolean | undefined;\n}\n\nexport async function handleSearch(args: {\n query: string;\n stores?: string;\n limit?: string;\n}): Promise<void> {\n // PWD is set by Claude Code to user's project directory\n const services = await createServices(undefined, undefined, process.env['PWD']);\n\n try {\n const storeNames = args.stores?.split(',').map((s: string) => s.trim());\n\n const allStores = await services.store.list();\n const targetStores =\n storeNames !== undefined ? allStores.filter((s) => storeNames.includes(s.name)) : allStores;\n\n if (targetStores.length === 0) {\n console.error('No stores found to search');\n process.exitCode = 1;\n return;\n }\n\n // Initialize stores\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const store of targetStores) {\n await services.lance.initialize(store.id);\n }\n\n const limitValue = args.limit ?? '10';\n const limit = parseInt(limitValue, 10);\n if (Number.isNaN(limit)) {\n throw new Error(`Invalid value for limit: \"${limitValue}\" is not a valid integer`);\n }\n\n const results = await services.search.search({\n query: args.query,\n stores: targetStores.map((s) => s.id),\n mode: 'hybrid',\n limit,\n detail: 'contextual',\n });\n\n console.log(`Found ${String(results.totalResults)} results:\\n`);\n for (const r of results.results) {\n if (r.summary !== undefined) {\n console.log(`Score: ${r.score.toFixed(2)} - ${r.summary.location}`);\n console.log(r.summary.purpose);\n }\n console.log('---');\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleAddRepo(\n args: {\n url: string;\n name?: string;\n branch?: string;\n },\n options: CommandOptions = {}\n): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const storeName = args.name ?? extractRepoName(args.url);\n\n console.log(`Cloning ${args.url}...`);\n\n const result = await services.store.create({\n name: storeName,\n type: 'repo',\n url: args.url,\n ...(args.branch !== undefined ? { branch: args.branch } : {}),\n });\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Created store: ${storeName} (${result.data.id})`);\n if ('path' in result.data) {\n console.log(`Location: ${result.data.path}`);\n }\n\n // Auto-index\n console.log('\\nIndexing...');\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(result.data.id);\n const indexResult = await services.index.indexStore(result.data);\n\n if (indexResult.success) {\n console.log(`Indexed ${String(indexResult.data.filesIndexed)} files`);\n } else {\n console.error(`Indexing failed: ${indexResult.error.message}`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleAddFolder(\n args: { path: string; name?: string },\n options: CommandOptions = {}\n): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const { basename } = await import('node:path');\n const storeName = args.name ?? basename(args.path);\n\n console.log(`Adding folder: ${args.path}...`);\n\n const result = await services.store.create({\n name: storeName,\n type: 'file',\n path: args.path,\n });\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Created store: ${storeName} (${result.data.id})`);\n if ('path' in result.data) {\n console.log(`Location: ${result.data.path}`);\n }\n\n // Auto-index\n console.log('\\nIndexing...');\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(result.data.id);\n const indexResult = await services.index.indexStore(result.data);\n\n if (indexResult.success) {\n console.log(`Indexed ${String(indexResult.data.filesIndexed)} files`);\n } else {\n console.error(`Indexing failed: ${indexResult.error.message}`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleIndex(args: { store: string }): Promise<void> {\n // PWD is set by Claude Code to user's project directory\n const services = await createServices(undefined, undefined, process.env['PWD']);\n\n try {\n const store = await services.store.getByIdOrName(args.store);\n\n if (store === undefined) {\n console.error(`Store not found: ${args.store}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Indexing ${store.name}...`);\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const result = await services.index.indexStore(store);\n\n if (result.success) {\n console.log(\n `Indexed ${String(result.data.filesIndexed)} documents in ${String(result.data.timeMs)}ms`\n );\n } else {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleStores(options: CommandOptions = {}): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const stores = await services.store.list();\n\n if (stores.length === 0) {\n console.log('No stores found.');\n console.log('\\nCreate a store with:');\n console.log(' /bluera-knowledge:add-repo <url> --name=<name>');\n console.log(' /bluera-knowledge:add-folder <path> --name=<name>');\n return;\n }\n\n // Table header\n console.log('| Name | Type | ID | Source |');\n console.log('|------|------|----|--------------------|');\n\n // Table rows\n for (const store of stores) {\n const name = store.name;\n const type = store.type;\n const id = store.id;\n let source = '';\n\n if ('url' in store && store.url !== undefined) {\n source = store.url;\n } else if ('path' in store) {\n source = store.path;\n }\n\n console.log(`| ${name} | ${type} | ${id.substring(0, 8)}... | ${source} |`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\n/**\n * Use Claude CLI to select the most important dependencies for BK indexing.\n * Falls back to top-N by usage frequency if Claude CLI is unavailable.\n */\nfunction filterImportantDeps(usages: PackageUsage[]): PackageUsage[] {\n if (usages.length <= 5) return usages;\n\n const depList = usages\n .map(\n (u) =>\n `- ${u.packageName}: ${String(u.importCount)} imports in ${String(u.fileCount)} files${u.isDevDependency ? ' (dev)' : ''}`\n )\n .join('\\n');\n\n const prompt = [\n \"Given this project's dependencies ranked by import frequency:\",\n '',\n depList,\n '',\n 'Select the dependencies that would be MOST VALUABLE to have their source code indexed for an AI coding assistant. Focus on:',\n '- Core frameworks and libraries the project builds on (not dev tools)',\n '- Libraries with complex APIs where understanding internals helps',\n '- Libraries likely to cause debugging issues or have non-obvious behavior',\n '- Skip: test runners, linters, formatters, build tools, @types packages, trivial utilities',\n '',\n 'Return ONLY a JSON array of package names, e.g.: [\"react\", \"prisma\", \"zod\"]',\n 'Do not explain. Just the JSON array.',\n ].join('\\n');\n\n const output = execSync('claude -p --output-format json --model haiku', {\n input: prompt,\n encoding: 'utf-8',\n timeout: 30000,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n const parsed: unknown = JSON.parse(output);\n const resultText = extractStringField(parsed, 'result');\n if (resultText === undefined) {\n throw new Error('Unexpected Claude CLI output format');\n }\n\n // Extract JSON array from response (Claude might wrap it in markdown code blocks)\n const jsonMatch = /\\[[\\s\\S]*\\]/.exec(resultText);\n if (jsonMatch === null) {\n throw new Error('No JSON array found in Claude response');\n }\n\n const selected: unknown = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(selected)) {\n throw new Error('Claude response is not an array');\n }\n\n const selectedNames = new Set(selected.filter((s): s is string => typeof s === 'string'));\n const filtered = usages.filter((u) => selectedNames.has(u.packageName));\n\n // If Claude filtered too aggressively (< 2 results), fall back\n if (filtered.length < 2) {\n throw new Error('Claude returned too few results');\n }\n\n return filtered;\n}\n\nexport async function handleSuggest(options: CommandOptions = {}): Promise<void> {\n const projectRoot = options.projectRoot ?? process.env['PWD'] ?? process.cwd();\n\n console.log('Analyzing project dependencies...\\n');\n\n // Create analyzer instance\n const services = await createServices(options.config, options.dataDir, projectRoot);\n\n try {\n const analyzer = new DependencyUsageAnalyzer();\n const resolver = new RepoUrlResolver();\n\n // Analyze with progress indicator\n const spinner = ora('Scanning source files...').start();\n\n const result = await analyzer.analyze(projectRoot, (current, total, message) => {\n spinner.text = `${message} (${String(current)}/${String(total)})`;\n });\n\n spinner.stop();\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n const { usages, totalFilesScanned, skippedFiles } = result.data;\n\n console.log(\n `✔ Scanned ${String(totalFilesScanned)} files${skippedFiles > 0 ? ` (skipped ${String(skippedFiles)})` : ''}\\n`\n );\n\n if (usages.length === 0) {\n console.log('No external dependencies found in this project.');\n console.log('\\nMake sure you have a package.json or requirements.txt file.');\n return;\n }\n\n // Filter out packages already in stores\n const existingStores = await services.store.list();\n const existingRepoNames = new Set(existingStores.map((s) => s.name));\n\n const newUsages = usages.filter((u) => !existingRepoNames.has(u.packageName));\n\n if (newUsages.length === 0) {\n console.log('✔ All dependencies are already in knowledge stores!');\n return;\n }\n\n // Use AI to select the most important dependencies for BK indexing\n let topSuggestions: PackageUsage[];\n try {\n const spinner2 = ora('Selecting important dependencies with AI...').start();\n topSuggestions = filterImportantDeps(newUsages);\n spinner2.stop();\n console.log('AI-selected dependencies most valuable for source indexing:\\n');\n } catch (error) {\n logger.debug(\n { error: error instanceof Error ? error.message : String(error) },\n 'AI filtering unavailable, falling back to top-5 by usage'\n );\n topSuggestions = newUsages.slice(0, 5);\n console.log('Top dependencies by usage in this project:\\n');\n }\n topSuggestions.forEach((usage, i) => {\n console.log(`${String(i + 1)}. ${usage.packageName}`);\n console.log(\n ` ${String(usage.importCount)} imports across ${String(usage.fileCount)} files\\n`\n );\n });\n\n console.log('Searching for repository URLs...\\n');\n\n // For each package, find repo URL\n for (const usage of topSuggestions) {\n const repoResult = await resolver.findRepoUrl(usage.packageName, usage.language);\n\n if (repoResult.url !== null) {\n console.log(`✔ ${usage.packageName}: ${repoResult.url}`);\n console.log(` /bluera-knowledge:add-repo ${repoResult.url} --name=${usage.packageName}\\n`);\n } else {\n console.log(`✗ ${usage.packageName}: Could not find repository URL`);\n console.log(\n ` You can manually add it: /bluera-knowledge:add-repo <url> --name=${usage.packageName}\\n`\n );\n }\n }\n\n console.log('Use the commands above to add repositories to your knowledge stores.');\n } finally {\n await destroyServices(services);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { join, extname } from 'node:path';\nimport { ASTParser } from './ast-parser.js';\nimport { ok, err } from '../types/result.js';\nimport type { SupportedLanguage } from './repo-url-resolver.js';\nimport type { Result } from '../types/result.js';\n\nconst TEXT_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.rb',\n '.go',\n '.java',\n '.rs',\n '.php',\n '.md',\n '.txt',\n '.json',\n '.yml',\n '.yaml',\n '.toml',\n]);\n\nexport interface PackageUsage {\n packageName: string;\n importCount: number;\n fileCount: number;\n files: string[];\n isDevDependency: boolean;\n language: SupportedLanguage;\n}\n\nexport interface DependencyAnalysisResult {\n usages: PackageUsage[];\n totalFilesScanned: number;\n skippedFiles: number;\n analysisTimeMs: number;\n}\n\ninterface DeclaredDependency {\n name: string;\n isDev: boolean;\n language: SupportedLanguage;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport class DependencyUsageAnalyzer {\n private readonly astParser: ASTParser;\n\n constructor() {\n this.astParser = new ASTParser();\n }\n\n async analyze(\n projectRoot: string,\n onProgress?: (current: number, total: number, message: string) => void\n ): Promise<Result<DependencyAnalysisResult>> {\n const startTime = Date.now();\n\n try {\n // 1. Read declared dependencies from package.json/requirements.txt\n const declaredDeps = await this.readDeclaredDependencies(projectRoot);\n\n if (declaredDeps.size === 0) {\n return ok({\n usages: [],\n totalFilesScanned: 0,\n skippedFiles: 0,\n analysisTimeMs: Date.now() - startTime,\n });\n }\n\n // 2. Scan all source files\n const files = await this.scanDirectory(projectRoot);\n\n if (files.length === 0) {\n return ok({\n usages: [],\n totalFilesScanned: 0,\n skippedFiles: 0,\n analysisTimeMs: Date.now() - startTime,\n });\n }\n\n // 3. Count imports for each package\n const usageMap = new Map<string, PackageUsage>();\n let processedCount = 0;\n let skippedCount = 0;\n\n for (const filePath of files) {\n try {\n const content = await readFile(filePath, 'utf-8');\n const imports = this.extractImportsForFile(filePath, content);\n\n for (const importInfo of imports) {\n const packageName = this.extractPackageName(importInfo.source);\n\n if (packageName !== null && declaredDeps.has(packageName)) {\n const dep = declaredDeps.get(packageName);\n if (dep !== undefined) {\n this.incrementUsage(usageMap, packageName, filePath, dep.isDev, dep.language);\n }\n }\n }\n\n processedCount++;\n if (onProgress !== undefined && processedCount % 10 === 0) {\n onProgress(\n processedCount,\n files.length,\n `Analyzed ${String(processedCount)}/${String(files.length)} files`\n );\n }\n } catch {\n // Skip files that can't be read or parsed\n skippedCount++;\n }\n }\n\n // 4. Sort by usage frequency\n const sortedUsages = Array.from(usageMap.values()).sort(\n (a, b) => b.importCount - a.importCount\n );\n\n return ok({\n usages: sortedUsages,\n totalFilesScanned: processedCount,\n skippedFiles: skippedCount,\n analysisTimeMs: Date.now() - startTime,\n });\n } catch (error) {\n const errorObj = new Error(\n error instanceof Error ? error.message : 'Unknown error during analysis'\n );\n errorObj.name = 'ANALYSIS_ERROR';\n return err(errorObj);\n }\n }\n\n private extractPackageName(importSource: string): string | null {\n // Relative imports (./foo, ../bar, /absolute) -> null\n if (importSource.startsWith('.') || importSource.startsWith('/')) {\n return null;\n }\n\n // Node built-ins (node:fs, node:path) -> null\n if (importSource.startsWith('node:')) {\n return null;\n }\n\n // Scoped packages: @org/package/path -> @org/package\n if (importSource.startsWith('@')) {\n const parts = importSource.split('/');\n if (parts.length >= 2 && parts[0] !== undefined && parts[1] !== undefined) {\n return `${parts[0]}/${parts[1]}`;\n }\n return null;\n }\n\n // Regular packages: lodash/get -> lodash\n const firstPart = importSource.split('/')[0];\n return firstPart ?? null;\n }\n\n private extractImportsForFile(filePath: string, content: string): Array<{ source: string }> {\n const ext = extname(filePath);\n\n // JavaScript/TypeScript - use AST parser\n if (['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'].includes(ext)) {\n try {\n return this.astParser.extractImports(content);\n } catch {\n // Fallback to regex for malformed files\n return this.extractImportsRegex(content, 'javascript');\n }\n }\n\n // Python - use regex\n if (ext === '.py') {\n return this.extractImportsRegex(content, 'python');\n }\n\n return [];\n }\n\n private extractImportsRegex(\n content: string,\n language: 'javascript' | 'python'\n ): Array<{ source: string }> {\n const imports: Array<{ source: string }> = [];\n\n if (language === 'javascript') {\n // Match: import ... from 'package'\n // Match: require('package')\n const importPattern = /import\\s+.*?from\\s+['\"]([^'\"]+)['\"]/g;\n const requirePattern = /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n for (const match of content.matchAll(importPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n\n for (const match of content.matchAll(requirePattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n } else {\n // Match: import package\n // Match: from package import ...\n const importPattern = /^import\\s+([a-zA-Z0-9_]+)/gm;\n const fromPattern = /^from\\s+([a-zA-Z0-9_]+)/gm;\n\n for (const match of content.matchAll(importPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n\n for (const match of content.matchAll(fromPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n }\n\n return imports;\n }\n\n private incrementUsage(\n usageMap: Map<string, PackageUsage>,\n packageName: string,\n filePath: string,\n isDevDependency: boolean,\n language: SupportedLanguage\n ): void {\n const existing = usageMap.get(packageName);\n\n if (existing) {\n existing.importCount++;\n if (!existing.files.includes(filePath)) {\n existing.fileCount++;\n existing.files.push(filePath);\n }\n } else {\n usageMap.set(packageName, {\n packageName,\n importCount: 1,\n fileCount: 1,\n files: [filePath],\n isDevDependency,\n language,\n });\n }\n }\n\n private async scanDirectory(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip common ignored directories\n if (\n ![\n 'node_modules',\n '.git',\n '.bluera',\n 'dist',\n 'build',\n 'coverage',\n '__pycache__',\n '.venv',\n 'venv',\n ].includes(entry.name)\n ) {\n files.push(...(await this.scanDirectory(fullPath)));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name);\n if (TEXT_EXTENSIONS.has(ext)) {\n files.push(fullPath);\n }\n }\n }\n } catch {\n // Ignore permission errors\n }\n\n return files;\n }\n\n private async readDeclaredDependencies(\n projectRoot: string\n ): Promise<Map<string, DeclaredDependency>> {\n const deps = new Map<string, DeclaredDependency>();\n\n // Read package.json (Node.js)\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n\n if (isRecord(parsed)) {\n // Regular dependencies\n if (isRecord(parsed['dependencies'])) {\n for (const name of Object.keys(parsed['dependencies'])) {\n deps.set(name, { name, isDev: false, language: 'javascript' });\n }\n }\n\n // Dev dependencies\n if (isRecord(parsed['devDependencies'])) {\n for (const name of Object.keys(parsed['devDependencies'])) {\n deps.set(name, { name, isDev: true, language: 'javascript' });\n }\n }\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Read requirements.txt (Python)\n const reqPath = join(projectRoot, 'requirements.txt');\n if (existsSync(reqPath)) {\n try {\n const content = await readFile(reqPath, 'utf-8');\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n\n // Parse package name (before ==, >=, etc.)\n const match = /^([a-zA-Z0-9_-]+)/.exec(trimmed);\n if (match?.[1] !== undefined) {\n const name = match[1].toLowerCase();\n deps.set(name, { name, isDev: false, language: 'python' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read pyproject.toml (Python)\n const pyprojectPath = join(projectRoot, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n try {\n const content = await readFile(pyprojectPath, 'utf-8');\n // Simple regex extraction (good enough for dependency names)\n const depMatches = content.matchAll(/\"([a-zA-Z0-9_-]+)\"/g);\n\n for (const match of depMatches) {\n if (match[1] !== undefined) {\n const name = match[1].toLowerCase();\n deps.set(name, { name, isDev: false, language: 'python' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read Cargo.toml (Rust)\n const cargoPath = join(projectRoot, 'Cargo.toml');\n if (existsSync(cargoPath)) {\n try {\n const content = await readFile(cargoPath, 'utf-8');\n // Match [dependencies] section entries like: serde = \"1.0\"\n // or serde = { version = \"1.0\", features = [...] }\n const inDepsSection = /\\[dependencies\\]([\\s\\S]*?)(?=\\n\\[|$)/;\n const depsMatch = inDepsSection.exec(content);\n if (depsMatch?.[1] !== undefined) {\n const depsSection = depsMatch[1];\n // Match crate names at start of lines\n const cratePattern = /^([a-zA-Z0-9_-]+)\\s*=/gm;\n for (const match of depsSection.matchAll(cratePattern)) {\n if (match[1] !== undefined) {\n deps.set(match[1], { name: match[1], isDev: false, language: 'rust' });\n }\n }\n }\n\n // Also check [dev-dependencies]\n const inDevDepsSection = /\\[dev-dependencies\\]([\\s\\S]*?)(?=\\n\\[|$)/;\n const devDepsMatch = inDevDepsSection.exec(content);\n if (devDepsMatch?.[1] !== undefined) {\n const devDepsSection = devDepsMatch[1];\n const cratePattern = /^([a-zA-Z0-9_-]+)\\s*=/gm;\n for (const match of devDepsSection.matchAll(cratePattern)) {\n if (match[1] !== undefined) {\n deps.set(match[1], { name: match[1], isDev: true, language: 'rust' });\n }\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read go.mod (Go)\n const goModPath = join(projectRoot, 'go.mod');\n if (existsSync(goModPath)) {\n try {\n const content = await readFile(goModPath, 'utf-8');\n // Match require blocks and single requires\n // require github.com/gorilla/mux v1.8.0\n // require (\n // github.com/gorilla/mux v1.8.0\n // )\n const requirePattern = /^\\s*([a-zA-Z0-9._/-]+)\\s+v[\\d.]+/gm;\n for (const match of content.matchAll(requirePattern)) {\n if (match[1] !== undefined && !match[1].startsWith('//')) {\n // Go modules use the full path as the name\n deps.set(match[1], { name: match[1], isDev: false, language: 'go' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n return deps;\n }\n}\n","export interface RepoSearchResult {\n url: string | null;\n confidence: 'high' | 'medium' | 'low';\n source: 'registry' | 'search' | 'fallback';\n}\n\n/**\n * Type guard to check if a value is a non-null object\n */\nfunction isObject(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport type SupportedLanguage = 'javascript' | 'python' | 'rust' | 'go';\n\nexport class RepoUrlResolver {\n /**\n * Find the GitHub repository URL for a package\n */\n async findRepoUrl(\n packageName: string,\n language: SupportedLanguage = 'javascript'\n ): Promise<RepoSearchResult> {\n // Strategy 1: Try package registry API (fast, accurate)\n let registryUrl: string | null = null;\n\n switch (language) {\n case 'javascript':\n registryUrl = await this.tryNpmRegistry(packageName);\n break;\n case 'python':\n registryUrl = await this.tryPyPiRegistry(packageName);\n break;\n case 'rust':\n registryUrl = await this.tryCratesRegistry(packageName);\n break;\n case 'go':\n registryUrl = await this.tryGoModule(packageName);\n break;\n }\n\n if (registryUrl !== null) {\n return { url: registryUrl, confidence: 'high', source: 'registry' };\n }\n\n // Strategy 2: No URL found\n return { url: null, confidence: 'low', source: 'fallback' };\n }\n\n /**\n * Query NPM registry for package metadata\n */\n private async tryNpmRegistry(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}`);\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL - safely access nested property\n if ('repository' in data) {\n const repo = data['repository'];\n if (isObject(repo) && 'url' in repo) {\n const urlValue = repo['url'];\n const url = String(urlValue);\n return this.normalizeRepoUrl(url);\n }\n\n if (typeof repo === 'string') {\n return this.normalizeRepoUrl(repo);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Query PyPI registry for package metadata\n */\n private async tryPyPiRegistry(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://pypi.org/pypi/${packageName}/json`);\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL from project URLs\n if ('info' in data) {\n const info = data['info'];\n if (isObject(info) && 'project_urls' in info) {\n const projectUrls = info['project_urls'];\n\n if (isObject(projectUrls)) {\n // Try various common keys\n const urlKeys = ['Source', 'Repository', 'Code', 'Homepage'];\n\n for (const key of urlKeys) {\n if (key in projectUrls) {\n const urlValue = projectUrls[key];\n const url = String(urlValue);\n if (url.includes('github.com')) {\n return this.normalizeRepoUrl(url);\n }\n }\n }\n }\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Query crates.io registry for Rust crate metadata\n */\n private async tryCratesRegistry(crateName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://crates.io/api/v1/crates/${crateName}`, {\n headers: {\n // crates.io requires a User-Agent header\n 'User-Agent': 'bluera-knowledge (https://github.com/blueraai/bluera-knowledge)',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL from crate metadata\n if ('crate' in data) {\n const crate = data['crate'];\n if (isObject(crate) && 'repository' in crate) {\n const repo = crate['repository'];\n if (typeof repo === 'string') {\n return this.normalizeRepoUrl(repo);\n }\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve Go module to GitHub repository\n * Go modules often use GitHub URLs directly (e.g., github.com/gorilla/mux)\n */\n private async tryGoModule(moduleName: string): Promise<string | null> {\n try {\n // Go modules that start with github.com are already GitHub URLs\n if (moduleName.startsWith('github.com/')) {\n // Extract owner/repo from module path (e.g., github.com/gorilla/mux/v2 -> github.com/gorilla/mux)\n const parts = moduleName.split('/');\n const owner = parts[1];\n const repo = parts[2];\n if (owner !== undefined && repo !== undefined) {\n return `https://github.com/${owner}/${repo}`;\n }\n }\n\n // For other modules, try pkg.go.dev API\n // The pkg.go.dev API returns module info including repository URL\n const response = await fetch(`https://proxy.golang.org/${moduleName}/@latest`, {\n headers: {\n 'User-Agent': 'bluera-knowledge (https://github.com/blueraai/bluera-knowledge)',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n // The Go proxy returns module info, but repository URL needs to be inferred\n // from the module path or VCS info. For now, we only support direct GitHub modules.\n // Most popular Go packages use github.com paths anyway.\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Normalize various repository URL formats to standard GitHub URL\n */\n private normalizeRepoUrl(url: string): string | null {\n // Remove git+ prefix\n let normalized = url.replace(/^git\\+/, '');\n\n // Remove .git suffix\n normalized = normalized.replace(/\\.git$/, '');\n\n // Convert git:// to https://\n normalized = normalized.replace(/^git:\\/\\//, 'https://');\n\n // Convert ssh:// to https://\n normalized = normalized.replace(/^ssh:\\/\\/git@/, 'https://');\n\n // Convert git@github.com: to https://github.com/\n normalized = normalized.replace(/^git@github\\.com:/, 'https://github.com/');\n\n // Only return if it's a GitHub URL\n if (normalized.includes('github.com')) {\n return normalized;\n }\n\n return null;\n }\n}\n","import { Command } from 'commander';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { SearchMode, DetailLevel } from '../../types/search.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createSearchCommand(getOptions: () => GlobalOptions): Command {\n const search = new Command('search')\n .description('Search indexed documents using vector similarity + full-text matching')\n .argument('<query>', 'Search query')\n .option(\n '-s, --stores <stores>',\n 'Limit search to specific stores (comma-separated IDs or names)'\n )\n .option(\n '-m, --mode <mode>',\n 'vector (embeddings only), fts (text only), hybrid (both, default)',\n 'hybrid'\n )\n .option('-n, --limit <count>', 'Maximum results to return (default: 10)', '10')\n .option('-t, --threshold <score>', 'Minimum score 0-1; omit low-relevance results')\n .option(\n '--min-relevance <score>',\n 'Minimum raw cosine similarity 0-1; returns empty if no results meet threshold'\n )\n .option(\n '--detail <level>',\n 'Context detail: minimal, contextual, full (default: minimal)',\n 'minimal'\n )\n .action(\n async (\n query: string,\n options: {\n stores?: string;\n mode: SearchMode;\n limit: string;\n threshold?: string;\n minRelevance?: string;\n detail: DetailLevel;\n }\n ) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n // Get store IDs\n let storeIds = (await services.store.list()).map((s) => s.id);\n\n searchLogic: {\n if (options.stores !== undefined) {\n const requestedStores = options.stores.split(',').map((s) => s.trim());\n const resolvedStores = [];\n\n for (const requested of requestedStores) {\n const store = await services.store.getByIdOrName(requested);\n if (store !== undefined) {\n resolvedStores.push(store.id);\n } else {\n console.error(`Error: Store not found: ${requested}`);\n exitCode = 3;\n\n break searchLogic;\n }\n }\n\n storeIds = resolvedStores;\n }\n\n if (storeIds.length === 0) {\n console.error('No stores to search. Create a store first.');\n exitCode = 1;\n\n break searchLogic;\n }\n\n // Initialize LanceDB for each store\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const storeId of storeIds) {\n await services.lance.initialize(storeId);\n }\n\n // Validate numeric options\n const limit = parseInt(options.limit, 10);\n if (Number.isNaN(limit)) {\n throw new Error(\n `Invalid value for --limit: \"${options.limit}\" is not a valid integer`\n );\n }\n\n let threshold: number | undefined;\n if (options.threshold !== undefined) {\n threshold = parseFloat(options.threshold);\n if (Number.isNaN(threshold)) {\n throw new Error(\n `Invalid value for --threshold: \"${options.threshold}\" is not a valid number`\n );\n }\n if (threshold < 0 || threshold > 1) {\n throw new Error(`Invalid value for --threshold: must be between 0 and 1`);\n }\n }\n\n let minRelevance: number | undefined;\n if (options.minRelevance !== undefined) {\n minRelevance = parseFloat(options.minRelevance);\n if (Number.isNaN(minRelevance)) {\n throw new Error(\n `Invalid value for --min-relevance: \"${options.minRelevance}\" is not a valid number`\n );\n }\n if (minRelevance < 0 || minRelevance > 1) {\n throw new Error(`Invalid value for --min-relevance: must be between 0 and 1`);\n }\n }\n\n const results = await services.search.search({\n query,\n stores: storeIds,\n mode: options.mode,\n limit,\n threshold,\n minRelevance,\n detail: options.detail,\n });\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(results, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: just list matching paths/URLs, one per line\n for (const r of results.results) {\n const path = r.metadata.path ?? r.metadata.url ?? 'unknown';\n console.log(path);\n }\n } else {\n console.log(`\\nSearch: \"${query}\"`);\n\n // Build status line with optional confidence info\n let statusLine = `Mode: ${results.mode} | Detail: ${options.detail} | Stores: ${String(results.stores.length)} | Results: ${String(results.totalResults)} | Time: ${String(results.timeMs)}ms`;\n if (results.confidence !== undefined) {\n statusLine += ` | Confidence: ${results.confidence}`;\n }\n if (results.maxRawScore !== undefined) {\n statusLine += ` | MaxRaw: ${results.maxRawScore.toFixed(3)}`;\n }\n if (results.rerankTimeMs !== undefined) {\n statusLine += ` | Rerank: ${String(results.rerankTimeMs)}ms`;\n }\n console.log(`${statusLine}\\n`);\n\n if (results.results.length === 0) {\n if (results.confidence === 'low') {\n console.log('No sufficiently relevant results found.\\n');\n } else {\n console.log('No results found.\\n');\n }\n } else {\n for (let i = 0; i < results.results.length; i++) {\n const r = results.results[i];\n if (r === undefined) continue;\n\n if (r.summary) {\n console.log(\n `${String(i + 1)}. [${r.score.toFixed(2)}] ${r.summary.type}: ${r.summary.name}`\n );\n console.log(` ${r.summary.location}`);\n console.log(` ${r.summary.purpose}`);\n\n // Contextual: Show imports, concepts, and usage stats\n if (r.context && options.detail !== 'minimal') {\n if (r.context.keyImports.length > 0) {\n console.log(` Imports: ${r.context.keyImports.slice(0, 3).join(', ')}`);\n }\n if (r.context.relatedConcepts.length > 0) {\n console.log(\n ` Related: ${r.context.relatedConcepts.slice(0, 3).join(', ')}`\n );\n }\n // Show usage stats from code graph\n const { calledBy, calls } = r.context.usage;\n if (calledBy > 0 || calls > 0) {\n console.log(\n ` Usage: Called by ${String(calledBy)} | Calls ${String(calls)}`\n );\n }\n }\n\n // Full: Show complete code and documentation\n if (r.full && options.detail === 'full') {\n if (r.full.completeCode) {\n console.log(` ---`);\n const codeLines = r.full.completeCode.split('\\n');\n console.log(` ${codeLines.slice(0, 10).join('\\n ')}`);\n if (codeLines.length > 10) {\n console.log(` ... (truncated)`);\n }\n }\n if (r.full.documentation) {\n console.log(` Doc: ${r.full.documentation.slice(0, 100)}`);\n }\n }\n\n console.log();\n } else {\n // Display without summary\n const path = r.metadata.path ?? r.metadata.url ?? 'unknown';\n console.log(`${String(i + 1)}. [${r.score.toFixed(2)}] ${path}`);\n const preview =\n r.highlight ??\n r.content.slice(0, 150).replace(/\\n/g, ' ') +\n (r.content.length > 150 ? '...' : '');\n console.log(` ${preview}\\n`);\n }\n }\n }\n }\n }\n } finally {\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n\n return search;\n}\n","import { serve } from '@hono/node-server';\nimport { Command } from 'commander';\nimport { createApp } from '../../server/app.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createServeCommand(getOptions: () => GlobalOptions): Command {\n return new Command('serve')\n .description('Start HTTP API server for programmatic search access')\n .option('-p, --port <port>', 'Port to listen on (reads from config if not specified)')\n .option(\n '--host <host>',\n 'Bind address (reads from config if not specified, use 0.0.0.0 for all interfaces)'\n )\n .action(async (options: { port?: string; host?: string }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n // Load config for defaults\n const appConfig = await services.config.load();\n const app = createApp(services);\n\n // Use config defaults, CLI flags override\n let port: number;\n if (options.port !== undefined) {\n port = parseInt(options.port, 10);\n if (Number.isNaN(port)) {\n throw new Error(`Invalid value for --port: \"${options.port}\" is not a valid integer`);\n }\n } else {\n port = appConfig.server.port;\n }\n const host = options.host ?? appConfig.server.host;\n\n console.log(`Starting server on http://${host}:${String(port)}`);\n\n const server = serve({\n fetch: app.fetch,\n port,\n hostname: host,\n });\n\n // Graceful shutdown: close HTTP server, then cleanup services.\n // Do NOT call process.exit() - let the event loop drain naturally\n // so native code (lancedb, ONNX) can clean up without mutex corruption.\n let shuttingDown = false;\n const shutdown = (): void => {\n if (shuttingDown) return; // Prevent double-shutdown\n shuttingDown = true;\n server.close(() => {\n void destroyServices(services);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","import { rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { z } from 'zod';\nimport type { ServiceContainer } from '../services/index.js';\nimport type { SearchQuery } from '../types/search.js';\n\n// HTTP API validation schemas (consistent with MCP schemas)\nconst CreateStoreBodySchema = z\n .object({\n name: z.string().min(1, 'Store name must be a non-empty string'),\n type: z.enum(['file', 'repo', 'web']),\n path: z.string().min(1).optional(),\n url: z.string().min(1).optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n branch: z.string().optional(),\n depth: z.number().int().positive().optional(),\n })\n .refine(\n (data) => {\n switch (data.type) {\n case 'file':\n return data.path !== undefined;\n case 'web':\n return data.url !== undefined;\n case 'repo':\n return data.path !== undefined || data.url !== undefined;\n }\n },\n {\n message:\n 'Missing required field: file stores need path, web stores need url, repo stores need path or url',\n }\n );\n\nconst SearchBodySchema = z.object({\n query: z.string().min(1, 'Query must be a non-empty string'),\n detail: z.enum(['minimal', 'contextual', 'full']).optional(),\n limit: z.number().int().positive().optional(),\n stores: z.array(z.string()).optional(),\n});\n\nexport function createApp(services: ServiceContainer): Hono {\n const app = new Hono();\n\n app.use('*', cors());\n\n // Health check\n app.get('/health', (c) => c.json({ status: 'ok' }));\n\n // Stores\n app.get('/api/stores', async (c) => {\n const stores = await services.store.list();\n return c.json(stores);\n });\n\n app.post('/api/stores', async (c) => {\n const jsonData: unknown = await c.req.json();\n const parseResult = CreateStoreBodySchema.safeParse(jsonData);\n if (!parseResult.success) {\n return c.json({ error: parseResult.error.issues[0]?.message ?? 'Invalid request body' }, 400);\n }\n const result = await services.store.create(parseResult.data);\n if (result.success) {\n return c.json(result.data, 201);\n }\n return c.json({ error: result.error.message }, 400);\n });\n\n app.get('/api/stores/:id', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n return c.json(store);\n });\n\n app.delete('/api/stores/:id', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n\n // Delete LanceDB table first (so searches don't return results for deleted store)\n await services.lance.deleteStore(store.id);\n\n // Delete code graph\n await services.codeGraph.deleteGraph(store.id);\n\n // Delete manifest\n await services.manifest.delete(store.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n // Only delete if path is within our data directory (cloned repos)\n const resolvedDataDir = services.config.resolveDataDir();\n if (\n store.type === 'repo' &&\n 'url' in store &&\n store.url !== undefined &&\n store.path.startsWith(join(resolvedDataDir, 'repos'))\n ) {\n await rm(store.path, { recursive: true, force: true });\n }\n\n // Delete from registry last\n const result = await services.store.delete(store.id);\n if (result.success) return c.json({ deleted: true });\n return c.json({ error: result.error.message }, 400);\n });\n\n // Search\n app.post('/api/search', async (c) => {\n const jsonData: unknown = await c.req.json();\n const parseResult = SearchBodySchema.safeParse(jsonData);\n if (!parseResult.success) {\n return c.json({ error: parseResult.error.issues[0]?.message ?? 'Invalid request body' }, 400);\n }\n\n const storeIds = (await services.store.list()).map((s) => s.id);\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const id of storeIds) {\n await services.lance.initialize(id);\n }\n\n // Resolve user-provided store strings to StoreIds, or use all stores\n let requestedStores = storeIds;\n if (parseResult.data.stores !== undefined) {\n const resolvedStores: typeof storeIds = [];\n for (const requested of parseResult.data.stores) {\n const store = await services.store.getByIdOrName(requested);\n if (store === undefined) {\n return c.json({ error: `Store not found: ${requested}` }, 404);\n }\n resolvedStores.push(store.id);\n }\n requestedStores = resolvedStores;\n }\n\n const query: SearchQuery = {\n query: parseResult.data.query,\n detail: parseResult.data.detail ?? 'minimal',\n limit: parseResult.data.limit ?? 10,\n stores: requestedStores,\n };\n const results = await services.search.search(query);\n return c.json(results);\n });\n\n // Index\n app.post('/api/stores/:id/index', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const result = await services.index.indexStore(store);\n\n if (result.success) return c.json(result.data);\n return c.json({ error: result.error.message }, 400);\n });\n\n return app;\n}\n","import { spawnSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { DEFAULT_REPOS, type DefaultRepo } from '../../defaults/repos.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { GlobalOptions } from '../program.js';\n\nconst DEFAULT_REPOS_DIR = join(homedir(), '.bluera', 'bluera-knowledge', 'repos');\n\nexport function createSetupCommand(getOptions: () => GlobalOptions): Command {\n const setup = new Command('setup').description(\n 'Quick-start with pre-configured Claude/Anthropic documentation repos'\n );\n\n setup\n .command('repos')\n .description(\n 'Clone repos to ~/.bluera/bluera-knowledge/repos/, create stores, index all content'\n )\n .option(\n '--repos-dir <path>',\n 'Clone destination (default: ~/.bluera/bluera-knowledge/repos/)',\n DEFAULT_REPOS_DIR\n )\n .option('--skip-clone', \"Don't clone; assume repos already exist locally\")\n .option('--skip-index', \"Clone and create stores but don't index yet\")\n .option('--only <names>', 'Only process matching repos (comma-separated, partial match)')\n .option('--list', 'Print available repos without cloning/indexing')\n .action(\n async (options: {\n reposDir: string;\n skipClone?: boolean;\n skipIndex?: boolean;\n only?: string;\n list?: boolean;\n }) => {\n const globalOpts = getOptions();\n\n // List mode: just show available repos\n if (options.list === true) {\n console.log('\\nDefault repositories:\\n');\n for (const repo of DEFAULT_REPOS) {\n console.log(` ${repo.name}`);\n console.log(` URL: ${repo.url}`);\n console.log(` Description: ${repo.description}`);\n console.log(` Tags: ${repo.tags.join(', ')}`);\n console.log('');\n }\n return;\n }\n\n // Filter repos BEFORE creating services to avoid cleanup bypass\n let repos: readonly DefaultRepo[] = DEFAULT_REPOS;\n if (options.only !== undefined && options.only !== '') {\n const onlyNames = options.only.split(',').map((n) => n.trim().toLowerCase());\n repos = DEFAULT_REPOS.filter((r) =>\n onlyNames.some((n) => r.name.toLowerCase().includes(n))\n );\n if (repos.length === 0) {\n console.error(`No repos matched: ${options.only}`);\n console.log('Available repos:', DEFAULT_REPOS.map((r) => r.name).join(', '));\n process.exitCode = 1;\n return;\n }\n }\n\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n try {\n console.log(`\\nSetting up ${String(repos.length)} repositories...\\n`);\n\n // Ensure repos directory exists\n await mkdir(options.reposDir, { recursive: true });\n\n for (const repo of repos) {\n const repoPath = join(options.reposDir, repo.name);\n const spinner = ora(`Processing ${repo.name}`).start();\n\n try {\n // Step 1: Clone if needed\n if (options.skipClone !== true) {\n if (existsSync(repoPath)) {\n spinner.text = `${repo.name}: Already cloned, pulling latest...`;\n const pullResult = spawnSync('git', ['pull', '--ff-only'], {\n cwd: repoPath,\n stdio: 'pipe',\n });\n if (pullResult.status !== 0) {\n // Pull failed (maybe diverged), that's okay\n spinner.text = `${repo.name}: Pull skipped (local changes)`;\n }\n } else {\n spinner.text = `${repo.name}: Cloning...`;\n const cloneResult = spawnSync('git', ['clone', repo.url, repoPath], {\n stdio: 'pipe',\n });\n if (cloneResult.status !== 0) {\n const errorMessage =\n cloneResult.stderr.length > 0\n ? cloneResult.stderr.toString()\n : 'Git clone failed';\n throw new Error(errorMessage);\n }\n }\n }\n\n // Step 2: Create store if needed\n spinner.text = `${repo.name}: Creating store...`;\n const existingStore = await services.store.getByIdOrName(repo.name);\n\n let storeId: string;\n if (existingStore) {\n storeId = existingStore.id;\n spinner.text = `${repo.name}: Store already exists`;\n } else {\n const result = await services.store.create({\n name: repo.name,\n type: 'repo',\n path: repoPath,\n description: repo.description,\n tags: repo.tags,\n });\n\n if (!result.success) {\n throw new Error(\n result.error instanceof Error ? result.error.message : String(result.error)\n );\n }\n storeId = result.data.id;\n }\n\n // Step 3: Index if needed\n if (options.skipIndex !== true) {\n spinner.text = `${repo.name}: Indexing...`;\n const store = await services.store.getByIdOrName(storeId);\n if (store) {\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const indexResult = await services.index.indexStore(store, (event) => {\n if (event.type === 'progress') {\n spinner.text = `${repo.name}: Indexing ${String(event.current)}/${String(event.total)} files`;\n }\n });\n\n if (indexResult.success) {\n spinner.succeed(\n `${repo.name}: ${String(indexResult.data.filesIndexed)} docs, ${String(indexResult.data.chunksCreated)} chunks`\n );\n } else {\n throw new Error(\n indexResult.error instanceof Error\n ? indexResult.error.message\n : String(indexResult.error)\n );\n }\n }\n } else {\n spinner.succeed(`${repo.name}: Ready (indexing skipped)`);\n }\n } catch (error) {\n spinner.fail(\n `${repo.name}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n console.log('\\nSetup complete! Use \"bluera-knowledge search <query>\" to search.\\n');\n } finally {\n await destroyServices(services);\n }\n }\n );\n\n return setup;\n}\n","/**\n * Default repositories for quick setup.\n * These are Anthropic/Claude-related repositories that provide\n * useful knowledge for Claude Code development.\n */\n\nexport interface DefaultRepo {\n /** Git URL for cloning */\n url: string;\n /** Friendly name for the store */\n name: string;\n /** Description of what this repo contains */\n description: string;\n /** Tags for categorization */\n tags: string[];\n}\n\nexport const DEFAULT_REPOS: readonly DefaultRepo[] = [\n {\n url: 'git@github.com:ericbuess/claude-code-docs.git',\n name: 'claude-code-docs',\n description: 'Claude Code documentation',\n tags: ['claude', 'docs', 'claude-code'],\n },\n {\n url: 'git@github.com:anthropics/claude-code.git',\n name: 'claude-code',\n description: 'Claude Code CLI tool source',\n tags: ['claude', 'cli', 'anthropic'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-python.git',\n name: 'claude-agent-sdk-python',\n description: 'Claude Agent SDK for Python',\n tags: ['claude', 'sdk', 'python', 'agents'],\n },\n {\n url: 'git@github.com:anthropics/skills.git',\n name: 'claude-skills',\n description: 'Claude skills and capabilities',\n tags: ['claude', 'skills'],\n },\n {\n url: 'git@github.com:anthropics/claude-quickstarts.git',\n name: 'claude-quickstarts',\n description: 'Claude quickstart examples and tutorials',\n tags: ['claude', 'examples', 'tutorials'],\n },\n {\n url: 'git@github.com:anthropics/claude-plugins-official.git',\n name: 'claude-plugins',\n description: 'Official Claude plugins',\n tags: ['claude', 'plugins'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-typescript.git',\n name: 'claude-agent-sdk-typescript',\n description: 'Claude Agent SDK for TypeScript',\n tags: ['claude', 'sdk', 'typescript', 'agents'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-demos.git',\n name: 'claude-agent-sdk-demos',\n description: 'Claude Agent SDK demo applications',\n tags: ['claude', 'sdk', 'demos', 'examples'],\n },\n];\n","import { rm, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport { isGitUrl } from '../../plugin/git-clone.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { checkStoreModelCompatibility } from '../../utils/model-validation.js';\nimport type { Store, StoreType } from '../../types/store.js';\nimport type { GlobalOptions } from '../program.js';\n\n/** Health check severity level */\ntype HealthSeverity = 'error' | 'warning';\n\n/** Health check issue code */\ntype HealthIssueCode = 'PATH_NOT_FOUND' | 'SCHEMA_V1' | 'MODEL_MISMATCH';\n\n/** A single health check issue */\ninterface HealthIssue {\n severity: HealthSeverity;\n code: HealthIssueCode;\n message: string;\n resolution: string;\n}\n\n/** Health check result for a single store */\ninterface HealthResult {\n storeId: string;\n storeName: string;\n storeType: StoreType;\n status: 'healthy' | 'warning' | 'error';\n issues: HealthIssue[];\n}\n\n/**\n * Check if a path exists\n */\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check health of a single store\n */\nasync function checkStoreHealth(store: Store, currentModelId: string): Promise<HealthResult> {\n const issues: HealthIssue[] = [];\n\n // 1. Path check - file/repo only\n if (store.type === 'file' || store.type === 'repo') {\n const exists = await pathExists(store.path);\n if (!exists) {\n issues.push({\n severity: 'error',\n code: 'PATH_NOT_FOUND',\n message: `Path does not exist: ${store.path}`,\n resolution: 'Re-create store or fix projectRoot if path was relative',\n });\n }\n }\n\n // 2. Model compatibility check (reuses existing validation)\n const modelCheck = checkStoreModelCompatibility(store, { currentModelId });\n if (!modelCheck.compatible) {\n const isSchemaV1 = modelCheck.reason?.includes('v1') === true;\n issues.push({\n severity: 'warning',\n code: isSchemaV1 ? 'SCHEMA_V1' : 'MODEL_MISMATCH',\n message: modelCheck.reason ?? 'Model incompatibility',\n resolution: `Run: bluera-knowledge index ${store.name}`,\n });\n }\n\n // Determine overall status\n const hasError = issues.some((i) => i.severity === 'error');\n const hasWarning = issues.some((i) => i.severity === 'warning');\n const status = hasError ? 'error' : hasWarning ? 'warning' : 'healthy';\n\n return {\n storeId: store.id,\n storeName: store.name,\n storeType: store.type,\n status,\n issues,\n };\n}\n\nexport function createStoreCommand(getOptions: () => GlobalOptions): Command {\n const store = new Command('store').description(\n 'Manage knowledge stores (collections of indexed documents)'\n );\n\n store\n .command('list')\n .description('Show all stores with their type (file/repo/web) and ID')\n .option('-t, --type <type>', 'Filter by type: file, repo, or web')\n .action(async (options: { type?: StoreType }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n try {\n const stores = await services.store.list(options.type);\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(stores, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: just list store names, one per line\n for (const s of stores) {\n console.log(s.name);\n }\n } else {\n if (stores.length === 0) {\n console.log('No stores found.');\n } else {\n console.log('\\nStores:\\n');\n for (const s of stores) {\n console.log(` ${s.name} (${s.type}) - ${s.id}`);\n }\n console.log('');\n }\n }\n } finally {\n await destroyServices(services);\n }\n });\n\n store\n .command('create <name>')\n .description('Create a new store pointing to a local path or URL')\n .requiredOption(\n '-t, --type <type>',\n 'Store type: file (local dir), repo (git), web (crawled site)'\n )\n .requiredOption('-s, --source <path>', 'Local path for file/repo stores, URL for web stores')\n .option('-b, --branch <branch>', 'Git branch to clone (repo stores only)')\n .option('-d, --description <desc>', 'Optional description for the store')\n .option('--tags <tags>', 'Comma-separated tags for filtering')\n .action(\n async (\n name: string,\n options: {\n type: StoreType;\n source: string;\n branch?: string;\n description?: string;\n tags?: string;\n }\n ) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n // Detect if source is a URL (for repo stores that should clone from remote)\n // Supports http://, https://, and git@ SSH URLs\n const isUrl = isGitUrl(options.source);\n const result = await services.store.create({\n name,\n type: options.type,\n path:\n options.type === 'file' || (options.type === 'repo' && !isUrl)\n ? options.source\n : undefined,\n url:\n options.type === 'web' || (options.type === 'repo' && isUrl)\n ? options.source\n : undefined,\n branch: options.type === 'repo' ? options.branch : undefined,\n description: options.description,\n tags: options.tags?.split(',').map((t) => t.trim()),\n });\n\n if (result.success) {\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.log(`\\nCreated store: ${result.data.name} (${result.data.id})\\n`);\n }\n } else {\n console.error(`Error: ${result.error.message}`);\n exitCode = 1;\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n\n store\n .command('info <store>')\n .description('Show store details: ID, type, path/URL, timestamps')\n .action(async (storeIdOrName: string) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n storeInfo: try {\n const s = await services.store.getByIdOrName(storeIdOrName);\n\n if (s === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n break storeInfo;\n }\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(s, null, 2));\n } else {\n console.log(`\\nStore: ${s.name}`);\n console.log(` ID: ${s.id}`);\n console.log(` Type: ${s.type}`);\n if ('path' in s) console.log(` Path: ${s.path}`);\n if ('url' in s && s.url !== undefined) console.log(` URL: ${s.url}`);\n if (s.description !== undefined) console.log(` Description: ${s.description}`);\n console.log(` Created: ${s.createdAt.toISOString()}`);\n console.log(` Updated: ${s.updatedAt.toISOString()}`);\n console.log('');\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n store\n .command('delete <store>')\n .description('Remove store and its indexed documents from LanceDB')\n .option('-f, --force', 'Delete without confirmation prompt')\n .option('-y, --yes', 'Alias for --force')\n .action(async (storeIdOrName: string, options: { force?: boolean; yes?: boolean }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n storeDelete: try {\n const s = await services.store.getByIdOrName(storeIdOrName);\n\n if (s === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n break storeDelete;\n }\n\n // Require --force or -y in non-TTY mode, prompt in TTY mode\n const skipConfirmation = options.force === true || options.yes === true;\n if (!skipConfirmation) {\n if (!process.stdin.isTTY) {\n console.error(\n 'Error: Use --force or -y to delete without confirmation in non-interactive mode'\n );\n exitCode = 1;\n break storeDelete;\n }\n // Interactive confirmation\n const readline = await import('node:readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n const answer = await new Promise<string>((resolve) => {\n rl.question(`Delete store \"${s.name}\"? [y/N] `, resolve);\n });\n rl.close();\n if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {\n console.log('Cancelled.');\n // exitCode stays 0 for user-initiated cancellation\n break storeDelete;\n }\n }\n\n // Delete LanceDB table first (so searches don't return results for deleted store)\n await services.lance.deleteStore(s.id);\n\n // Delete code graph file\n await services.codeGraph.deleteGraph(s.id);\n\n // Delete manifest file (matches MCP/server behavior)\n await services.manifest.delete(s.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n if (s.type === 'repo' && 'url' in s && s.url !== undefined) {\n const dataDir = services.config.resolveDataDir();\n const repoPath = join(dataDir, 'repos', s.id);\n await rm(repoPath, { recursive: true, force: true });\n }\n\n // Delete from registry last\n const result = await services.store.delete(s.id);\n\n if (result.success) {\n console.log(`Deleted store: ${s.name}`);\n } else {\n console.error(`Error: ${result.error.message}`);\n exitCode = 1;\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n store\n .command('health')\n .description('Check health of all stores: path existence, model compatibility')\n .option('-s, --store <name>', 'Check a specific store only')\n .action(async (options: { store?: string }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n const currentModelId = services.store.getCurrentModelId();\n let storesToCheck: Store[];\n\n if (options.store !== undefined) {\n const s = await services.store.getByIdOrName(options.store);\n if (s === undefined) {\n console.error(`Error: Store not found: ${options.store}`);\n exitCode = 1;\n return;\n }\n storesToCheck = [s];\n } else {\n storesToCheck = await services.store.list();\n }\n\n if (storesToCheck.length === 0) {\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify({ stores: [], exitCode: 0 }, null, 2));\n } else if (globalOpts.quiet !== true) {\n console.log('No stores found.');\n }\n return;\n }\n\n // Check health of each store\n const results: HealthResult[] = [];\n for (const s of storesToCheck) {\n const result = await checkStoreHealth(s, currentModelId);\n results.push(result);\n }\n\n // Determine exit code: 1 for any error, 2 for warning-only, 0 for healthy\n const hasError = results.some((r) => r.status === 'error');\n const hasWarning = results.some((r) => r.status === 'warning');\n exitCode = hasError ? 1 : hasWarning ? 2 : 0;\n\n // Output results\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify({ stores: results, exitCode }, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: no output, just exit code\n } else {\n // Human-readable output\n console.log('\\nStore Health Check\\n');\n for (const result of results) {\n const statusIcon =\n result.status === 'healthy' ? '✓' : result.status === 'warning' ? '⚠' : '✗';\n const statusColor =\n result.status === 'healthy'\n ? '\\x1b[32m'\n : result.status === 'warning'\n ? '\\x1b[33m'\n : '\\x1b[31m';\n const reset = '\\x1b[0m';\n\n console.log(\n ` ${statusColor}${statusIcon}${reset} ${result.storeName} (${result.storeType})`\n );\n for (const issue of result.issues) {\n const issueIcon = issue.severity === 'error' ? ' ✗' : ' ⚠';\n console.log(` ${issueIcon} ${issue.message}`);\n console.log(` Fix: ${issue.resolution}`);\n }\n }\n\n // Summary\n const healthy = results.filter((r) => r.status === 'healthy').length;\n const warnings = results.filter((r) => r.status === 'warning').length;\n const errors = results.filter((r) => r.status === 'error').length;\n console.log('');\n console.log(\n `Summary: ${String(healthy)} healthy, ${String(warnings)} warnings, ${String(errors)} errors`\n );\n console.log('');\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n process.exitCode = exitCode;\n }\n });\n\n return store;\n}\n","import { rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { JobService } from '../../services/job.service.js';\nimport { ProjectRootService } from '../../services/project-root.service.js';\nimport { StoreDefinitionService } from '../../services/store-definition.service.js';\nimport {\n isFileStoreDefinition,\n isRepoStoreDefinition,\n isWebStoreDefinition,\n} from '../../types/store-definition.js';\nimport { spawnBackgroundWorker } from '../../workers/spawn-worker.js';\nimport type { StoreService } from '../../services/store.service.js';\nimport type { StoreDefinition } from '../../types/store-definition.js';\nimport type { GlobalOptions } from '../program.js';\n\ninterface SyncResult {\n created: string[];\n skipped: string[];\n failed: Array<{ name: string; error: string }>;\n orphans: string[];\n pruned: string[];\n dryRun: boolean;\n wouldCreate: string[];\n wouldPrune: string[];\n reindexJobs: Array<{ store: string; jobId: string }>;\n wouldReindex: string[];\n}\n\n/**\n * Create a store from a definition\n */\nasync function createStoreFromDefinition(\n def: StoreDefinition,\n defService: StoreDefinitionService,\n storeService: StoreService\n): Promise<{ success: true } | { success: false; error: string }> {\n try {\n if (isFileStoreDefinition(def)) {\n const resolvedPath = defService.resolvePath(def.path);\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'file',\n path: resolvedPath,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n if (isRepoStoreDefinition(def)) {\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'repo',\n url: def.url,\n branch: def.branch,\n depth: def.depth,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n if (isWebStoreDefinition(def)) {\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'web',\n url: def.url,\n depth: def.depth,\n maxPages: def.maxPages,\n crawlInstructions: def.crawlInstructions,\n extractInstructions: def.extractInstructions,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n return { success: false, error: 'Unknown store definition type' };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport function createSyncCommand(getOptions: () => GlobalOptions): Command {\n const sync = new Command('sync').description(\n 'Sync stores from definitions config (bootstrap on fresh clone)'\n );\n\n sync\n .option('--dry-run', 'Show what would happen without making changes')\n .option('--prune', 'Remove stores not in definitions')\n .option('--reindex', 'Re-index existing stores after sync')\n .action(async (options: { dryRun?: boolean; prune?: boolean; reindex?: boolean }) => {\n const globalOpts = getOptions();\n const projectRoot = globalOpts.projectRoot ?? ProjectRootService.resolve();\n\n const defService = new StoreDefinitionService(projectRoot);\n const services = await createServices(globalOpts.config, globalOpts.dataDir, projectRoot);\n\n try {\n const config = await defService.load();\n const existingStores = await services.store.list();\n const existingNames = new Set(existingStores.map((s) => s.name));\n const definedNames = new Set(config.stores.map((d) => d.name));\n\n const result: SyncResult = {\n created: [],\n skipped: [],\n failed: [],\n orphans: [],\n pruned: [],\n dryRun: options.dryRun === true,\n wouldCreate: [],\n wouldPrune: [],\n reindexJobs: [],\n wouldReindex: [],\n };\n\n // Process each definition\n for (const def of config.stores) {\n if (existingNames.has(def.name)) {\n result.skipped.push(def.name);\n continue;\n }\n\n if (options.dryRun === true) {\n result.wouldCreate.push(def.name);\n continue;\n }\n\n const createResult = await createStoreFromDefinition(def, defService, services.store);\n if (createResult.success) {\n result.created.push(def.name);\n } else {\n result.failed.push({ name: def.name, error: createResult.error });\n }\n }\n\n // Find orphans\n for (const store of existingStores) {\n if (!definedNames.has(store.name)) {\n result.orphans.push(store.name);\n }\n }\n\n // Prune orphans if requested\n if (options.prune === true && result.orphans.length > 0) {\n if (options.dryRun === true) {\n result.wouldPrune = [...result.orphans];\n } else {\n for (const orphanName of result.orphans) {\n const store = await services.store.getByName(orphanName);\n if (store !== undefined) {\n // Full cleanup like store delete command\n await services.lance.deleteStore(store.id);\n await services.codeGraph.deleteGraph(store.id);\n await services.manifest.delete(store.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n if (store.type === 'repo' && 'url' in store && store.url !== undefined) {\n const dataDir = services.config.resolveDataDir();\n const repoPath = join(dataDir, 'repos', store.id);\n await rm(repoPath, { recursive: true, force: true });\n }\n\n const deleteResult = await services.store.delete(store.id, {\n skipDefinitionSync: true,\n });\n if (deleteResult.success) {\n result.pruned.push(orphanName);\n }\n }\n }\n }\n }\n\n // Re-index existing stores if requested\n if (options.reindex === true && result.skipped.length > 0) {\n if (options.dryRun === true) {\n result.wouldReindex = [...result.skipped];\n } else {\n const dataDir = globalOpts.dataDir ?? services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n\n for (const storeName of result.skipped) {\n const store = await services.store.getByName(storeName);\n if (store !== undefined) {\n const job = jobService.createJob({\n type: 'index',\n details: { storeId: store.id, storeName: store.name },\n message: `Re-indexing ${storeName}...`,\n });\n spawnBackgroundWorker(job.id, dataDir);\n result.reindexJobs.push({ store: storeName, jobId: job.id });\n }\n }\n }\n }\n\n // Output result\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n printHumanReadable(result, globalOpts.quiet === true);\n }\n } finally {\n await destroyServices(services);\n }\n });\n\n return sync;\n}\n\nfunction printHumanReadable(result: SyncResult, quiet: boolean): void {\n if (quiet) {\n // Just print created/pruned/reindexed store names\n for (const name of result.created) {\n console.log(`created: ${name}`);\n }\n for (const name of result.pruned) {\n console.log(`pruned: ${name}`);\n }\n for (const { store, jobId } of result.reindexJobs) {\n console.log(`reindexing: ${store} (${jobId})`);\n }\n for (const name of result.wouldCreate) {\n console.log(`would create: ${name}`);\n }\n for (const name of result.wouldPrune) {\n console.log(`would prune: ${name}`);\n }\n for (const name of result.wouldReindex) {\n console.log(`would reindex: ${name}`);\n }\n return;\n }\n\n if (result.dryRun) {\n console.log('\\n[DRY RUN] No changes made.\\n');\n } else {\n console.log('\\nSync completed.\\n');\n }\n\n if (result.created.length > 0) {\n console.log(`Created (${String(result.created.length)}):`);\n for (const name of result.created) {\n console.log(` + ${name}`);\n }\n }\n\n if (result.wouldCreate.length > 0) {\n console.log(`Would create (${String(result.wouldCreate.length)}):`);\n for (const name of result.wouldCreate) {\n console.log(` + ${name}`);\n }\n }\n\n if (result.skipped.length > 0) {\n console.log(`Skipped (already exist) (${String(result.skipped.length)}):`);\n for (const name of result.skipped) {\n console.log(` - ${name}`);\n }\n }\n\n if (result.failed.length > 0) {\n console.log(`Failed (${String(result.failed.length)}):`);\n for (const { name, error } of result.failed) {\n console.log(` ! ${name}: ${error}`);\n }\n }\n\n if (result.orphans.length > 0) {\n console.log(`Orphans (not in definitions) (${String(result.orphans.length)}):`);\n for (const name of result.orphans) {\n console.log(` ? ${name}`);\n }\n }\n\n if (result.pruned.length > 0) {\n console.log(`Pruned (${String(result.pruned.length)}):`);\n for (const name of result.pruned) {\n console.log(` x ${name}`);\n }\n }\n\n if (result.wouldPrune.length > 0) {\n console.log(`Would prune (${String(result.wouldPrune.length)}):`);\n for (const name of result.wouldPrune) {\n console.log(` x ${name}`);\n }\n }\n\n if (result.reindexJobs.length > 0) {\n console.log(`Reindexing started (${String(result.reindexJobs.length)}):`);\n for (const { store, jobId } of result.reindexJobs) {\n console.log(` ↻ ${store} (Job: ${jobId})`);\n }\n }\n\n if (result.wouldReindex.length > 0) {\n console.log(`Would reindex (${String(result.wouldReindex.length)}):`);\n for (const name of result.wouldReindex) {\n console.log(` ↻ ${name}`);\n }\n }\n\n console.log('');\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\n\ninterface PackageJson {\n version: string;\n}\n\nfunction getVersion(): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const content = readFileSync(join(__dirname, '../package.json'), 'utf-8');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const pkg: PackageJson = JSON.parse(content);\n return pkg.version;\n}\n\nconst version = getVersion();\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('bluera-knowledge')\n .description('CLI tool for managing knowledge stores with semantic search')\n .version(version);\n\n program\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --data-dir <path>', 'Data directory')\n .option('-p, --project-root <path>', 'Project root directory (for resolving relative paths)')\n .option('-f, --format <format>', 'Output format: json | table | plain', 'table')\n .option('-q, --quiet', 'Suppress non-essential output');\n\n return program;\n}\n\nexport interface GlobalOptions {\n config?: string | undefined;\n dataDir?: string | undefined;\n projectRoot?: string | undefined;\n format: 'json' | 'table' | 'plain';\n quiet?: boolean | undefined;\n}\n\nexport function getGlobalOptions(program: Command): GlobalOptions {\n const opts = program.opts<GlobalOptions>();\n return {\n config: opts.config,\n dataDir: opts.dataDir,\n projectRoot: opts.projectRoot,\n format: opts.format,\n quiet: opts.quiet,\n };\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { AdapterRegistry } from './analysis/adapter-registry.js';\nimport { ZilAdapter } from './analysis/zil/index.js';\nimport { createCrawlCommand } from './cli/commands/crawl.js';\nimport { createIndexCommand } from './cli/commands/index-cmd.js';\nimport { createMCPCommand } from './cli/commands/mcp.js';\nimport {\n createAddRepoCommand,\n createAddFolderCommand,\n createStoresCommand,\n createSuggestCommand,\n} from './cli/commands/plugin-api.js';\nimport { createSearchCommand } from './cli/commands/search.js';\nimport { createServeCommand } from './cli/commands/serve.js';\nimport { createSetupCommand } from './cli/commands/setup.js';\nimport { createStoreCommand } from './cli/commands/store.js';\nimport { createSyncCommand } from './cli/commands/sync.js';\nimport { createProgram, getGlobalOptions } from './cli/program.js';\n\n// Register built-in language adapters\nconst registry = AdapterRegistry.getInstance();\nregistry.register(new ZilAdapter());\n\n// Default paths (for help text display only - actual paths resolved by ConfigService)\nconst DEFAULT_DATA_DIR = '.bluera/bluera-knowledge/data';\nconst DEFAULT_CONFIG = '.bluera/bluera-knowledge/config.json';\nconst DEFAULT_REPOS_DIR = '.bluera/bluera-knowledge/data/repos/<store-id>/';\n\n/**\n * Format a command and its subcommands recursively for comprehensive help output.\n */\nfunction formatCommandHelp(cmd: Command, indent: string = ''): string[] {\n const lines: string[] = [];\n const name = cmd.name();\n const desc = cmd.description();\n const args = cmd.registeredArguments\n .map((a) => {\n const req = a.required;\n return req ? `<${a.name()}>` : `[${a.name()}]`;\n })\n .join(' ');\n\n // Command header with arguments\n lines.push(`${indent}${name}${args ? ` ${args}` : ''}`);\n if (desc) {\n lines.push(`${indent} ${desc}`);\n }\n\n // Options (skip -h, --help which is auto-added)\n const options = cmd.options.filter((o) => o.flags !== '-h, --help');\n for (const opt of options) {\n lines.push(`${indent} ${opt.flags.padEnd(28)} ${opt.description}`);\n }\n\n // Subcommands (recursive)\n const subcommands = cmd.commands.filter((c) => c.name() !== 'help');\n for (const sub of subcommands) {\n lines.push('');\n lines.push(...formatCommandHelp(sub, `${indent} `));\n }\n\n return lines;\n}\n\n/**\n * Print comprehensive help showing all commands, subcommands, and options.\n */\nfunction printFullHelp(program: Command): void {\n console.log('bluera-knowledge - CLI tool for managing knowledge stores with semantic search\\n');\n\n // Active paths\n console.log('Paths:');\n console.log(` data ${DEFAULT_DATA_DIR}`);\n console.log(` config ${DEFAULT_CONFIG}`);\n console.log(` repos ${DEFAULT_REPOS_DIR}`);\n\n // Global options\n console.log('\\nGlobal options:');\n const globalOpts = program.options.filter(\n (o) => o.flags !== '-h, --help' && o.flags !== '-V, --version'\n );\n for (const opt of globalOpts) {\n console.log(` ${opt.flags.padEnd(28)} ${opt.description}`);\n }\n\n console.log('\\nCommands:\\n');\n\n // All commands except help\n const commands = program.commands.filter((c) => c.name() !== 'help');\n for (const cmd of commands) {\n console.log(formatCommandHelp(cmd).join('\\n'));\n console.log('');\n }\n}\n\nconst program = createProgram();\n\n// Plugin API commands (simple interface)\nprogram.addCommand(createAddRepoCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createAddFolderCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createStoresCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSuggestCommand(() => getGlobalOptions(program)));\n\n// Advanced CLI commands\nprogram.addCommand(createStoreCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSearchCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createIndexCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createServeCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createCrawlCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSetupCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSyncCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createMCPCommand(() => getGlobalOptions(program)));\n\n// Show comprehensive help when no arguments provided\nif (process.argv.length <= 2) {\n printFullHelp(program);\n process.exit(0);\n}\n\nprogram.parse();\n"],"mappings":"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","names":["url","Command","ora","Command","ora","err","Command","Command","Command","ora","ora","Command","Command","Command","Command","join","Command","existsSync","join","Command","ora","join","Command","ora","existsSync","rm","join","Command","Command","join","rm","rm","join","Command","Command","join","rm","join","Command","__filename","__dirname","program","DEFAULT_REPOS_DIR","program"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/crawl.ts","../src/cli/commands/index-cmd.ts","../src/cli/commands/mcp.ts","../src/cli/commands/plugin-api.ts","../src/plugin/commands.ts","../src/analysis/dependency-usage-analyzer.ts","../src/analysis/repo-url-resolver.ts","../src/cli/commands/search.ts","../src/cli/commands/serve.ts","../src/server/app.ts","../src/server/ui/admin.ts","../src/cli/commands/setup.ts","../src/defaults/repos.ts","../src/cli/commands/store.ts","../src/cli/commands/sync.ts","../src/cli/program.ts","../src/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { Command } from 'commander';\nimport ora, { type Ora } from 'ora';\nimport {\n getCrawlStrategy,\n IntelligentCrawler,\n type CrawlProgress,\n} from '../../crawl/intelligent-crawler.js';\nimport { ChunkingService } from '../../services/chunking.service.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { classifyWebContentType } from '../../services/index.service.js';\nimport { createDocumentId } from '../../types/brands.js';\nimport type { Document } from '../../types/document.js';\nimport type { WebStore } from '../../types/store.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createCrawlCommand(getOptions: () => GlobalOptions): Command {\n return new Command('crawl')\n .description('Crawl web pages with natural language control and index into store')\n .argument('<url>', 'URL to crawl')\n .argument('<store>', 'Target web store to add crawled content to')\n .option(\n '--crawl <instruction>',\n 'Natural language instruction for what to crawl (e.g., \"all Getting Started pages\")'\n )\n .option(\n '--extract <instruction>',\n 'Natural language instruction for what to extract (e.g., \"extract API references\")'\n )\n .option('--max-pages <number>', 'Maximum number of pages to crawl', '50')\n .option('--fast', 'Use fast axios-only mode (may fail on JavaScript-heavy sites)')\n .allowUnknownOption() // Allow --store= to be parsed so we can show helpful error\n .action(\n async (\n url: string,\n storeIdOrName: string,\n cmdOptions: {\n crawl?: string;\n extract?: string;\n maxPages: string;\n fast?: boolean;\n }\n ) => {\n // Detect common mistake: using --store= instead of positional argument\n const storeArg = process.argv.find((arg) => arg.startsWith('--store'));\n if (storeArg !== undefined) {\n const storeName = storeArg.includes('=') ? storeArg.split('=')[1] : 'NAME';\n const storeNameDisplay =\n storeName !== undefined && storeName !== '' ? storeName : 'my-store';\n console.error(`\nError: Store name should be a positional argument, not an option.\n\n WRONG: crawl ${url} ${storeArg}\n RIGHT: crawl ${url} ${storeNameDisplay}\n\nExample: bluera-knowledge crawl https://docs.example.com my-docs\n`);\n process.exitCode = 1;\n return;\n }\n\n const globalOpts = getOptions();\n const useHeadless = !(cmdOptions.fast ?? false);\n\n // IMPORTANT: Get crawl strategy BEFORE initializing lancedb services.\n // LanceDB's native Rust code is not fork-safe. Spawning Claude CLI after\n // lancedb is loaded corrupts the mutex state, causing crashes.\n const crawlInstruction = cmdOptions.crawl ?? 'crawl all pages linked from this URL';\n\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Crawling ${url}`);\n console.log('Analyzing page structure with Claude...');\n }\n const preComputedStrategy = await getCrawlStrategy(url, crawlInstruction, useHeadless);\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(\n `Claude identified ${String(preComputedStrategy.urls.length)} URLs: ${preComputedStrategy.reasoning}`\n );\n }\n\n // Now safe to initialize lancedb services\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n // Look up or auto-create web store\n let store: WebStore;\n let storeCreated = false;\n const existingStore = await services.store.getByIdOrName(storeIdOrName);\n\n if (!existingStore) {\n // Auto-create web store\n const result = await services.store.create({\n name: storeIdOrName,\n type: 'web',\n url,\n });\n if (!result.success) {\n await destroyServices(services);\n throw new Error(`Failed to create store: ${result.error.message}`);\n }\n // Type narrowing: success check above ensures result.data is Store\n // We know it's a WebStore because we created it with type: 'web'\n const createdStore = result.data;\n if (createdStore.type !== 'web') {\n throw new Error('Unexpected store type after creation');\n }\n store = createdStore;\n storeCreated = true;\n if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Created web store: ${store.name}`);\n }\n } else if (existingStore.type !== 'web') {\n await destroyServices(services);\n throw new Error(\n `Store \"${storeIdOrName}\" exists but is not a web store (type: ${existingStore.type})`\n );\n } else {\n store = existingStore;\n }\n\n const maxPages = parseInt(cmdOptions.maxPages, 10);\n if (Number.isNaN(maxPages)) {\n throw new Error(\n `Invalid value for --max-pages: \"${cmdOptions.maxPages}\" is not a valid integer`\n );\n }\n\n // Use spinner in interactive mode\n const isInteractive =\n process.stdout.isTTY && globalOpts.quiet !== true && globalOpts.format !== 'json';\n let spinner: Ora | undefined;\n\n if (isInteractive) {\n spinner = ora(`Crawling ${url} (intelligent mode)`).start();\n } else if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Crawling ${url}`);\n }\n\n const appConfig = await services.config.load();\n const crawler = new IntelligentCrawler(appConfig.crawl);\n // Use web preset for larger prose-friendly chunks\n const webChunker = ChunkingService.forContentType('web');\n let pagesIndexed = 0;\n let chunksCreated = 0;\n let exitCode = 0;\n\n // Listen for progress events\n crawler.on('progress', (progress: CrawlProgress) => {\n if (spinner) {\n if (progress.type === 'strategy') {\n spinner.text = progress.message ?? 'Analyzing crawl strategy...';\n } else if (progress.type === 'page') {\n const url = progress.currentUrl ?? 'unknown';\n spinner.text = `Crawling ${String(progress.pagesVisited + 1)}/${String(maxPages)} - ${url}`;\n } else if (progress.type === 'extraction') {\n const url = progress.currentUrl ?? 'unknown';\n spinner.text = `Extracting from ${url}...`;\n } else if (progress.type === 'error' && progress.message !== undefined) {\n spinner.warn(progress.message);\n }\n }\n });\n\n try {\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const docs: Document[] = [];\n\n // Crawl pages using IntelligentCrawler\n for await (const result of crawler.crawl(url, {\n crawlInstruction,\n ...(cmdOptions.extract !== undefined && { extractInstruction: cmdOptions.extract }),\n maxPages,\n useHeadless,\n preComputedStrategy,\n })) {\n // Use extracted content if available, otherwise markdown\n const contentToProcess = result.extracted ?? result.markdown;\n\n // Chunk the content using markdown-aware chunking (web content is converted to markdown)\n const chunks = webChunker.chunk(contentToProcess, `${result.url}.md`);\n const fileType = classifyWebContentType(result.url, result.title);\n const urlHash = createHash('md5').update(result.url).digest('hex');\n\n for (const chunk of chunks) {\n const chunkId =\n chunks.length > 1\n ? `${store.id}-${urlHash}-${String(chunk.chunkIndex)}`\n : `${store.id}-${urlHash}`;\n const vector = await services.embeddings.embedDocument(chunk.content);\n\n docs.push({\n id: createDocumentId(chunkId),\n content: chunk.content,\n vector,\n metadata: {\n type: chunks.length > 1 ? 'chunk' : 'web',\n storeId: store.id,\n url: result.url,\n title: result.title,\n extracted: result.extracted !== undefined,\n depth: result.depth,\n indexedAt: new Date().toISOString(),\n fileType,\n chunkIndex: chunk.chunkIndex,\n totalChunks: chunk.totalChunks,\n sectionHeader: chunk.sectionHeader,\n },\n });\n chunksCreated++;\n }\n\n pagesIndexed++;\n }\n\n // Index all documents\n if (docs.length > 0) {\n if (spinner) {\n spinner.text = 'Indexing documents...';\n }\n // Clear existing documents to prevent duplicates on re-crawl\n await services.lance.clearAllDocuments(store.id);\n await services.lance.addDocuments(store.id, docs);\n // Create FTS index for full-text search\n await services.lance.createFtsIndex(store.id);\n }\n\n const crawlResult = {\n success: true,\n store: store.name,\n storeCreated,\n url,\n pagesCrawled: pagesIndexed,\n chunksCreated,\n mode: 'intelligent',\n hadCrawlInstruction: cmdOptions.crawl !== undefined,\n hadExtractInstruction: cmdOptions.extract !== undefined,\n };\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(crawlResult, null, 2));\n } else if (spinner !== undefined) {\n spinner.succeed(\n `Crawled ${String(pagesIndexed)} pages, indexed ${String(chunksCreated)} chunks`\n );\n } else if (globalOpts.quiet !== true) {\n console.log(\n `Crawled ${String(pagesIndexed)} pages, indexed ${String(chunksCreated)} chunks`\n );\n }\n } catch (error) {\n const message = `Crawl failed: ${error instanceof Error ? error.message : String(error)}`;\n if (spinner) {\n spinner.fail(message);\n } else {\n console.error(`Error: ${message}`);\n }\n exitCode = 6;\n } finally {\n await crawler.stop();\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Using process.exitCode avoids mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n}\n","import { Command } from 'commander';\nimport ora, { type Ora } from 'ora';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { JobService } from '../../services/job.service.js';\nimport { validateStoreModelCompatibility } from '../../utils/model-validation.js';\nimport { spawnBackgroundWorker } from '../../workers/spawn-worker.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createIndexCommand(getOptions: () => GlobalOptions): Command {\n const index = new Command('index')\n .description('Scan store files, chunk text, generate embeddings, save to LanceDB')\n .argument('<store>', 'Store ID or name')\n .option('--force', 'Re-index all files even if unchanged')\n .action(async (storeIdOrName: string, options: { force?: boolean }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n indexLogic: {\n const store = await services.store.getByIdOrName(storeIdOrName);\n\n if (store === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n\n break indexLogic;\n }\n\n // Web stores need to be re-crawled, not re-indexed\n // Route to background crawl job\n if (store.type === 'web') {\n const dataDir = services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n const job = jobService.createJob({\n type: 'crawl',\n details: {\n storeName: store.name,\n storeId: store.id,\n url: store.url,\n maxPages: store.maxPages,\n crawlInstruction: store.crawlInstructions,\n extractInstruction: store.extractInstructions,\n phase: 'crawling',\n phaseStep: 1,\n phaseTotalSteps: 2,\n },\n message: `Re-crawling ${store.name}...`,\n });\n spawnBackgroundWorker(job.id, dataDir);\n\n if (globalOpts.format === 'json') {\n console.log(\n JSON.stringify(\n {\n store: { id: store.id, name: store.name, type: store.type },\n job: { id: job.id, status: job.status },\n message: `Re-crawl queued (Job ID: ${job.id})`,\n },\n null,\n 2\n )\n );\n } else if (globalOpts.quiet !== true) {\n console.log(`Re-crawl job queued for ${store.name} (Job ID: ${job.id})`);\n console.log(`Check status: bluera-knowledge jobs status ${job.id}`);\n }\n\n break indexLogic;\n }\n\n // Use spinner in interactive mode (not quiet, not json output)\n const isInteractive =\n process.stdout.isTTY && globalOpts.quiet !== true && globalOpts.format !== 'json';\n let spinner: Ora | undefined;\n\n if (isInteractive) {\n spinner = ora(`Indexing store: ${store.name}`).start();\n } else if (globalOpts.quiet !== true && globalOpts.format !== 'json') {\n console.log(`Indexing store: ${store.name}`);\n }\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n\n // Validate model compatibility for incremental indexing (not --force)\n // Full reindex is always allowed since it replaces all data\n if (options.force !== true) {\n const currentModelId = services.store.getCurrentModelId();\n validateStoreModelCompatibility(store, { currentModelId });\n }\n\n // Use full re-index with --force, otherwise incremental (default)\n const progressCallback = (event: {\n type: string;\n current: number;\n total: number;\n message: string;\n }): void => {\n if (event.type === 'progress') {\n if (spinner) {\n spinner.text = `Indexing: ${String(event.current)}/${String(event.total)} files - ${event.message}`;\n }\n }\n };\n\n const result =\n options.force === true\n ? await services.index.indexStore(store, progressCallback)\n : await services.index.indexStoreIncremental(store, progressCallback);\n\n if (result.success) {\n // Upgrade schema v1 stores to v2 after successful reindex\n // This adds modelId so the store becomes searchable\n if (!store.modelId) {\n await services.store.upgradeStoreSchema(store.id);\n }\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result.data, null, 2));\n } else {\n const message = `Indexed ${String(result.data.filesIndexed)} documents, ${String(result.data.chunksCreated)} chunks in ${String(result.data.timeMs)}ms`;\n if (spinner !== undefined) {\n spinner.succeed(message);\n } else if (globalOpts.quiet !== true) {\n console.log(message);\n }\n }\n } else {\n const message = `Error: ${result.error.message}`;\n if (spinner !== undefined) {\n spinner.fail(message);\n } else {\n console.error(message);\n }\n exitCode = 4;\n\n break indexLogic;\n }\n }\n } finally {\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Using process.exitCode avoids mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n index\n .command('watch <store>')\n .description('Watch store directory; re-index when files change')\n .option(\n '--debounce <ms>',\n 'Wait N ms after last change before re-indexing (default: 1000)',\n '1000'\n )\n .action(async (storeIdOrName: string, options: { debounce: string }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n const store = await services.store.getByIdOrName(storeIdOrName);\n if (store === undefined || (store.type !== 'file' && store.type !== 'repo')) {\n console.error(`Error: File/repo store not found: ${storeIdOrName}`);\n // Cleanup services before exiting (using exitCode avoids mutex crashes)\n await destroyServices(services);\n process.exitCode = 3;\n return;\n }\n\n const appConfig = await services.config.load();\n const { WatchService } = await import('../../services/watch.service.js');\n const watchService = new WatchService(services.index, services.lance, services.embeddings, {\n ignorePatterns: appConfig.indexing.ignorePatterns,\n currentModelId: services.store.getCurrentModelId(),\n });\n\n const debounceMs = parseInt(options.debounce, 10);\n if (Number.isNaN(debounceMs)) {\n throw new Error(\n `Invalid value for --debounce: \"${options.debounce}\" is not a valid integer`\n );\n }\n\n if (globalOpts.quiet !== true) {\n console.log(`Watching ${store.name} for changes...`);\n }\n await watchService.watch(\n store,\n debounceMs,\n () => {\n if (globalOpts.quiet !== true) {\n console.log(`Re-indexed ${store.name}`);\n }\n },\n (error: Error) => {\n console.error(`Watch error: ${error.message}`);\n }\n );\n\n // Keep process alive\n process.on('SIGINT', () => {\n void (async (): Promise<void> => {\n await watchService.unwatchAll();\n await destroyServices(services);\n process.exit(0);\n })().catch((err: unknown) => {\n console.error('Shutdown error:', err);\n process.exit(1);\n });\n });\n });\n\n return index;\n}\n","import { Command } from 'commander';\nimport { runMCPServer } from '../../mcp/server.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createMCPCommand(getOptions: () => GlobalOptions): Command {\n const mcp = new Command('mcp')\n .description('Start MCP (Model Context Protocol) server for AI agent integration')\n .action(async () => {\n const opts = getOptions();\n\n await runMCPServer({\n dataDir: opts.dataDir,\n config: opts.config,\n projectRoot: opts.projectRoot,\n });\n });\n\n return mcp;\n}\n","import { Command } from 'commander';\nimport {\n handleAddRepo,\n handleAddFolder,\n handleStores,\n handleSuggest,\n} from '../../plugin/commands.js';\nimport type { GlobalOptions } from '../program.js';\n\n/**\n * CLI commands that mirror the plugin API for consistency.\n * These commands provide a simpler interface that matches the plugin commands.\n */\n\nexport function createAddRepoCommand(getOptions: () => GlobalOptions): Command {\n return new Command('add-repo')\n .description('Clone and index a library source repository')\n .argument('<url>', 'Git repository URL')\n .option('--name <name>', 'Store name (defaults to repo name)')\n .option('--branch <branch>', 'Git branch to clone')\n .action(async (url: string, options: { name?: string; branch?: string }) => {\n const globalOpts = getOptions();\n await handleAddRepo(\n { url, ...options },\n {\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n }\n );\n });\n}\n\nexport function createAddFolderCommand(getOptions: () => GlobalOptions): Command {\n return new Command('add-folder')\n .description('Index a local folder of reference material')\n .argument('<path>', 'Folder path to index')\n .option('--name <name>', 'Store name (defaults to folder name)')\n .action(async (path: string, options: { name?: string }) => {\n const globalOpts = getOptions();\n await handleAddFolder(\n { path, ...options },\n {\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n }\n );\n });\n}\n\nexport function createStoresCommand(getOptions: () => GlobalOptions): Command {\n return new Command('stores').description('List all indexed library stores').action(async () => {\n const globalOpts = getOptions();\n await handleStores({\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n });\n });\n}\n\nexport function createSuggestCommand(getOptions: () => GlobalOptions): Command {\n return new Command('suggest')\n .description('Suggest important dependencies to add to knowledge stores')\n .action(async () => {\n const globalOpts = getOptions();\n await handleSuggest({\n config: globalOpts.config,\n dataDir: globalOpts.dataDir,\n projectRoot: globalOpts.projectRoot,\n format: globalOpts.format,\n quiet: globalOpts.quiet,\n });\n });\n}\n","import { execSync } from 'node:child_process';\nimport ora from 'ora';\nimport { extractRepoName } from './git-clone.js';\nimport { DependencyUsageAnalyzer } from '../analysis/dependency-usage-analyzer.js';\nimport { RepoUrlResolver } from '../analysis/repo-url-resolver.js';\nimport { createLogger } from '../logging/index.js';\nimport { createServices, destroyServices } from '../services/index.js';\nimport type { PackageUsage } from '../analysis/dependency-usage-analyzer.js';\n\nconst logger = createLogger('plugin-commands');\n\n/** Safely extract a string field from an unknown parsed JSON value. */\nfunction extractStringField(obj: unknown, key: string): string | undefined {\n if (typeof obj !== 'object' || obj === null || !(key in obj)) return undefined;\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor === undefined) return undefined;\n const value: unknown = descriptor.value;\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Options passed from CLI global options to plugin command handlers.\n */\nexport interface CommandOptions {\n config?: string | undefined;\n dataDir?: string | undefined;\n projectRoot?: string | undefined;\n format?: 'json' | 'table' | 'plain' | undefined;\n quiet?: boolean | undefined;\n}\n\nexport async function handleSearch(args: {\n query: string;\n stores?: string;\n limit?: string;\n}): Promise<void> {\n // PWD is set by Claude Code to user's project directory\n const services = await createServices(undefined, undefined, process.env['PWD']);\n\n try {\n const storeNames = args.stores?.split(',').map((s: string) => s.trim());\n\n const allStores = await services.store.list();\n const targetStores =\n storeNames !== undefined ? allStores.filter((s) => storeNames.includes(s.name)) : allStores;\n\n if (targetStores.length === 0) {\n console.error('No stores found to search');\n process.exitCode = 1;\n return;\n }\n\n // Initialize stores\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const store of targetStores) {\n await services.lance.initialize(store.id);\n }\n\n const limitValue = args.limit ?? '10';\n const limit = parseInt(limitValue, 10);\n if (Number.isNaN(limit)) {\n throw new Error(`Invalid value for limit: \"${limitValue}\" is not a valid integer`);\n }\n\n const results = await services.search.search({\n query: args.query,\n stores: targetStores.map((s) => s.id),\n mode: 'hybrid',\n limit,\n detail: 'contextual',\n });\n\n console.log(`Found ${String(results.totalResults)} results:\\n`);\n for (const r of results.results) {\n if (r.summary !== undefined) {\n console.log(`Score: ${r.score.toFixed(2)} - ${r.summary.location}`);\n console.log(r.summary.purpose);\n }\n console.log('---');\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleAddRepo(\n args: {\n url: string;\n name?: string;\n branch?: string;\n },\n options: CommandOptions = {}\n): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const storeName = args.name ?? extractRepoName(args.url);\n\n console.log(`Cloning ${args.url}...`);\n\n const result = await services.store.create({\n name: storeName,\n type: 'repo',\n url: args.url,\n ...(args.branch !== undefined ? { branch: args.branch } : {}),\n });\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Created store: ${storeName} (${result.data.id})`);\n if ('path' in result.data) {\n console.log(`Location: ${result.data.path}`);\n }\n\n // Auto-index\n console.log('\\nIndexing...');\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(result.data.id);\n const indexResult = await services.index.indexStore(result.data);\n\n if (indexResult.success) {\n console.log(`Indexed ${String(indexResult.data.filesIndexed)} files`);\n } else {\n console.error(`Indexing failed: ${indexResult.error.message}`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleAddFolder(\n args: { path: string; name?: string },\n options: CommandOptions = {}\n): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const { basename } = await import('node:path');\n const storeName = args.name ?? basename(args.path);\n\n console.log(`Adding folder: ${args.path}...`);\n\n const result = await services.store.create({\n name: storeName,\n type: 'file',\n path: args.path,\n });\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Created store: ${storeName} (${result.data.id})`);\n if ('path' in result.data) {\n console.log(`Location: ${result.data.path}`);\n }\n\n // Auto-index\n console.log('\\nIndexing...');\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(result.data.id);\n const indexResult = await services.index.indexStore(result.data);\n\n if (indexResult.success) {\n console.log(`Indexed ${String(indexResult.data.filesIndexed)} files`);\n } else {\n console.error(`Indexing failed: ${indexResult.error.message}`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleIndex(args: { store: string }): Promise<void> {\n // PWD is set by Claude Code to user's project directory\n const services = await createServices(undefined, undefined, process.env['PWD']);\n\n try {\n const store = await services.store.getByIdOrName(args.store);\n\n if (store === undefined) {\n console.error(`Store not found: ${args.store}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Indexing ${store.name}...`);\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const result = await services.index.indexStore(store);\n\n if (result.success) {\n console.log(\n `Indexed ${String(result.data.filesIndexed)} documents in ${String(result.data.timeMs)}ms`\n );\n } else {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n } finally {\n await destroyServices(services);\n }\n}\n\nexport async function handleStores(options: CommandOptions = {}): Promise<void> {\n const services = await createServices(\n options.config,\n options.dataDir,\n options.projectRoot ?? process.env['PWD']\n );\n\n try {\n const stores = await services.store.list();\n\n if (stores.length === 0) {\n console.log('No stores found.');\n console.log('\\nCreate a store with:');\n console.log(' /bluera-knowledge:add-repo <url> --name=<name>');\n console.log(' /bluera-knowledge:add-folder <path> --name=<name>');\n return;\n }\n\n // Table header\n console.log('| Name | Type | ID | Source |');\n console.log('|------|------|----|--------------------|');\n\n // Table rows\n for (const store of stores) {\n const name = store.name;\n const type = store.type;\n const id = store.id;\n let source = '';\n\n if ('url' in store && store.url !== undefined) {\n source = store.url;\n } else if ('path' in store) {\n source = store.path;\n }\n\n console.log(`| ${name} | ${type} | ${id.substring(0, 8)}... | ${source} |`);\n }\n } finally {\n await destroyServices(services);\n }\n}\n\n/**\n * Use Claude CLI to select the most important dependencies for BK indexing.\n * Falls back to top-N by usage frequency if Claude CLI is unavailable.\n */\nfunction filterImportantDeps(usages: PackageUsage[]): PackageUsage[] {\n if (usages.length <= 5) return usages;\n\n const depList = usages\n .map(\n (u) =>\n `- ${u.packageName}: ${String(u.importCount)} imports in ${String(u.fileCount)} files${u.isDevDependency ? ' (dev)' : ''}`\n )\n .join('\\n');\n\n const prompt = [\n \"Given this project's dependencies ranked by import frequency:\",\n '',\n depList,\n '',\n 'Select the dependencies that would be MOST VALUABLE to have their source code indexed for an AI coding assistant. Focus on:',\n '- Core frameworks and libraries the project builds on (not dev tools)',\n '- Libraries with complex APIs where understanding internals helps',\n '- Libraries likely to cause debugging issues or have non-obvious behavior',\n '- Skip: test runners, linters, formatters, build tools, @types packages, trivial utilities',\n '',\n 'Return ONLY a JSON array of package names, e.g.: [\"react\", \"prisma\", \"zod\"]',\n 'Do not explain. Just the JSON array.',\n ].join('\\n');\n\n const output = execSync('claude -p --output-format json --model haiku', {\n input: prompt,\n encoding: 'utf-8',\n timeout: 30000,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n const parsed: unknown = JSON.parse(output);\n const resultText = extractStringField(parsed, 'result');\n if (resultText === undefined) {\n throw new Error('Unexpected Claude CLI output format');\n }\n\n // Extract JSON array from response (Claude might wrap it in markdown code blocks)\n const jsonMatch = /\\[[\\s\\S]*\\]/.exec(resultText);\n if (jsonMatch === null) {\n throw new Error('No JSON array found in Claude response');\n }\n\n const selected: unknown = JSON.parse(jsonMatch[0]);\n if (!Array.isArray(selected)) {\n throw new Error('Claude response is not an array');\n }\n\n const selectedNames = new Set(selected.filter((s): s is string => typeof s === 'string'));\n const filtered = usages.filter((u) => selectedNames.has(u.packageName));\n\n // If Claude filtered too aggressively (< 2 results), fall back\n if (filtered.length < 2) {\n throw new Error('Claude returned too few results');\n }\n\n return filtered;\n}\n\nexport async function handleSuggest(options: CommandOptions = {}): Promise<void> {\n const projectRoot = options.projectRoot ?? process.env['PWD'] ?? process.cwd();\n\n console.log('Analyzing project dependencies...\\n');\n\n // Create analyzer instance\n const services = await createServices(options.config, options.dataDir, projectRoot);\n\n try {\n const analyzer = new DependencyUsageAnalyzer();\n const resolver = new RepoUrlResolver();\n\n // Analyze with progress indicator\n const spinner = ora('Scanning source files...').start();\n\n const result = await analyzer.analyze(projectRoot, (current, total, message) => {\n spinner.text = `${message} (${String(current)}/${String(total)})`;\n });\n\n spinner.stop();\n\n if (!result.success) {\n console.error(`Error: ${result.error.message}`);\n process.exitCode = 1;\n return;\n }\n\n const { usages, totalFilesScanned, skippedFiles } = result.data;\n\n console.log(\n `✔ Scanned ${String(totalFilesScanned)} files${skippedFiles > 0 ? ` (skipped ${String(skippedFiles)})` : ''}\\n`\n );\n\n if (usages.length === 0) {\n console.log('No external dependencies found in this project.');\n console.log('\\nMake sure you have a package.json or requirements.txt file.');\n return;\n }\n\n // Filter out packages already in stores\n const existingStores = await services.store.list();\n const existingRepoNames = new Set(existingStores.map((s) => s.name));\n\n const newUsages = usages.filter((u) => !existingRepoNames.has(u.packageName));\n\n if (newUsages.length === 0) {\n console.log('✔ All dependencies are already in knowledge stores!');\n return;\n }\n\n // Use AI to select the most important dependencies for BK indexing\n let topSuggestions: PackageUsage[];\n try {\n const spinner2 = ora('Selecting important dependencies with AI...').start();\n topSuggestions = filterImportantDeps(newUsages);\n spinner2.stop();\n console.log('AI-selected dependencies most valuable for source indexing:\\n');\n } catch (error) {\n logger.debug(\n { error: error instanceof Error ? error.message : String(error) },\n 'AI filtering unavailable, falling back to top-5 by usage'\n );\n topSuggestions = newUsages.slice(0, 5);\n console.log('Top dependencies by usage in this project:\\n');\n }\n topSuggestions.forEach((usage, i) => {\n console.log(`${String(i + 1)}. ${usage.packageName}`);\n console.log(\n ` ${String(usage.importCount)} imports across ${String(usage.fileCount)} files\\n`\n );\n });\n\n console.log('Searching for repository URLs...\\n');\n\n // For each package, find repo URL\n for (const usage of topSuggestions) {\n const repoResult = await resolver.findRepoUrl(usage.packageName, usage.language);\n\n if (repoResult.url !== null) {\n console.log(`✔ ${usage.packageName}: ${repoResult.url}`);\n console.log(` /bluera-knowledge:add-repo ${repoResult.url} --name=${usage.packageName}\\n`);\n } else {\n console.log(`✗ ${usage.packageName}: Could not find repository URL`);\n console.log(\n ` You can manually add it: /bluera-knowledge:add-repo <url> --name=${usage.packageName}\\n`\n );\n }\n }\n\n console.log('Use the commands above to add repositories to your knowledge stores.');\n } finally {\n await destroyServices(services);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { join, extname } from 'node:path';\nimport { ASTParser } from './ast-parser.js';\nimport { ok, err } from '../types/result.js';\nimport type { SupportedLanguage } from './repo-url-resolver.js';\nimport type { Result } from '../types/result.js';\n\nconst TEXT_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.rb',\n '.go',\n '.java',\n '.rs',\n '.php',\n '.md',\n '.txt',\n '.json',\n '.yml',\n '.yaml',\n '.toml',\n]);\n\nexport interface PackageUsage {\n packageName: string;\n importCount: number;\n fileCount: number;\n files: string[];\n isDevDependency: boolean;\n language: SupportedLanguage;\n}\n\nexport interface DependencyAnalysisResult {\n usages: PackageUsage[];\n totalFilesScanned: number;\n skippedFiles: number;\n analysisTimeMs: number;\n}\n\ninterface DeclaredDependency {\n name: string;\n isDev: boolean;\n language: SupportedLanguage;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport class DependencyUsageAnalyzer {\n private readonly astParser: ASTParser;\n\n constructor() {\n this.astParser = new ASTParser();\n }\n\n async analyze(\n projectRoot: string,\n onProgress?: (current: number, total: number, message: string) => void\n ): Promise<Result<DependencyAnalysisResult>> {\n const startTime = Date.now();\n\n try {\n // 1. Read declared dependencies from package.json/requirements.txt\n const declaredDeps = await this.readDeclaredDependencies(projectRoot);\n\n if (declaredDeps.size === 0) {\n return ok({\n usages: [],\n totalFilesScanned: 0,\n skippedFiles: 0,\n analysisTimeMs: Date.now() - startTime,\n });\n }\n\n // 2. Scan all source files\n const files = await this.scanDirectory(projectRoot);\n\n if (files.length === 0) {\n return ok({\n usages: [],\n totalFilesScanned: 0,\n skippedFiles: 0,\n analysisTimeMs: Date.now() - startTime,\n });\n }\n\n // 3. Count imports for each package\n const usageMap = new Map<string, PackageUsage>();\n let processedCount = 0;\n let skippedCount = 0;\n\n for (const filePath of files) {\n try {\n const content = await readFile(filePath, 'utf-8');\n const imports = this.extractImportsForFile(filePath, content);\n\n for (const importInfo of imports) {\n const packageName = this.extractPackageName(importInfo.source);\n\n if (packageName !== null && declaredDeps.has(packageName)) {\n const dep = declaredDeps.get(packageName);\n if (dep !== undefined) {\n this.incrementUsage(usageMap, packageName, filePath, dep.isDev, dep.language);\n }\n }\n }\n\n processedCount++;\n if (onProgress !== undefined && processedCount % 10 === 0) {\n onProgress(\n processedCount,\n files.length,\n `Analyzed ${String(processedCount)}/${String(files.length)} files`\n );\n }\n } catch {\n // Skip files that can't be read or parsed\n skippedCount++;\n }\n }\n\n // 4. Sort by usage frequency\n const sortedUsages = Array.from(usageMap.values()).sort(\n (a, b) => b.importCount - a.importCount\n );\n\n return ok({\n usages: sortedUsages,\n totalFilesScanned: processedCount,\n skippedFiles: skippedCount,\n analysisTimeMs: Date.now() - startTime,\n });\n } catch (error) {\n const errorObj = new Error(\n error instanceof Error ? error.message : 'Unknown error during analysis'\n );\n errorObj.name = 'ANALYSIS_ERROR';\n return err(errorObj);\n }\n }\n\n private extractPackageName(importSource: string): string | null {\n // Relative imports (./foo, ../bar, /absolute) -> null\n if (importSource.startsWith('.') || importSource.startsWith('/')) {\n return null;\n }\n\n // Node built-ins (node:fs, node:path) -> null\n if (importSource.startsWith('node:')) {\n return null;\n }\n\n // Scoped packages: @org/package/path -> @org/package\n if (importSource.startsWith('@')) {\n const parts = importSource.split('/');\n if (parts.length >= 2 && parts[0] !== undefined && parts[1] !== undefined) {\n return `${parts[0]}/${parts[1]}`;\n }\n return null;\n }\n\n // Regular packages: lodash/get -> lodash\n const firstPart = importSource.split('/')[0];\n return firstPart ?? null;\n }\n\n private extractImportsForFile(filePath: string, content: string): Array<{ source: string }> {\n const ext = extname(filePath);\n\n // JavaScript/TypeScript - use AST parser\n if (['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'].includes(ext)) {\n try {\n return this.astParser.extractImports(content);\n } catch {\n // Fallback to regex for malformed files\n return this.extractImportsRegex(content, 'javascript');\n }\n }\n\n // Python - use regex\n if (ext === '.py') {\n return this.extractImportsRegex(content, 'python');\n }\n\n return [];\n }\n\n private extractImportsRegex(\n content: string,\n language: 'javascript' | 'python'\n ): Array<{ source: string }> {\n const imports: Array<{ source: string }> = [];\n\n if (language === 'javascript') {\n // Match: import ... from 'package'\n // Match: require('package')\n const importPattern = /import\\s+.*?from\\s+['\"]([^'\"]+)['\"]/g;\n const requirePattern = /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n for (const match of content.matchAll(importPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n\n for (const match of content.matchAll(requirePattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n } else {\n // Match: import package\n // Match: from package import ...\n const importPattern = /^import\\s+([a-zA-Z0-9_]+)/gm;\n const fromPattern = /^from\\s+([a-zA-Z0-9_]+)/gm;\n\n for (const match of content.matchAll(importPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n\n for (const match of content.matchAll(fromPattern)) {\n if (match[1] !== undefined) imports.push({ source: match[1] });\n }\n }\n\n return imports;\n }\n\n private incrementUsage(\n usageMap: Map<string, PackageUsage>,\n packageName: string,\n filePath: string,\n isDevDependency: boolean,\n language: SupportedLanguage\n ): void {\n const existing = usageMap.get(packageName);\n\n if (existing) {\n existing.importCount++;\n if (!existing.files.includes(filePath)) {\n existing.fileCount++;\n existing.files.push(filePath);\n }\n } else {\n usageMap.set(packageName, {\n packageName,\n importCount: 1,\n fileCount: 1,\n files: [filePath],\n isDevDependency,\n language,\n });\n }\n }\n\n private async scanDirectory(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip common ignored directories\n if (\n ![\n 'node_modules',\n '.git',\n '.bluera',\n 'dist',\n 'build',\n 'coverage',\n '__pycache__',\n '.venv',\n 'venv',\n ].includes(entry.name)\n ) {\n files.push(...(await this.scanDirectory(fullPath)));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name);\n if (TEXT_EXTENSIONS.has(ext)) {\n files.push(fullPath);\n }\n }\n }\n } catch {\n // Ignore permission errors\n }\n\n return files;\n }\n\n private async readDeclaredDependencies(\n projectRoot: string\n ): Promise<Map<string, DeclaredDependency>> {\n const deps = new Map<string, DeclaredDependency>();\n\n // Read package.json (Node.js)\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const parsed: unknown = JSON.parse(content);\n\n if (isRecord(parsed)) {\n // Regular dependencies\n if (isRecord(parsed['dependencies'])) {\n for (const name of Object.keys(parsed['dependencies'])) {\n deps.set(name, { name, isDev: false, language: 'javascript' });\n }\n }\n\n // Dev dependencies\n if (isRecord(parsed['devDependencies'])) {\n for (const name of Object.keys(parsed['devDependencies'])) {\n deps.set(name, { name, isDev: true, language: 'javascript' });\n }\n }\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Read requirements.txt (Python)\n const reqPath = join(projectRoot, 'requirements.txt');\n if (existsSync(reqPath)) {\n try {\n const content = await readFile(reqPath, 'utf-8');\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n\n // Parse package name (before ==, >=, etc.)\n const match = /^([a-zA-Z0-9_-]+)/.exec(trimmed);\n if (match?.[1] !== undefined) {\n const name = match[1].toLowerCase();\n deps.set(name, { name, isDev: false, language: 'python' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read pyproject.toml (Python)\n const pyprojectPath = join(projectRoot, 'pyproject.toml');\n if (existsSync(pyprojectPath)) {\n try {\n const content = await readFile(pyprojectPath, 'utf-8');\n // Simple regex extraction (good enough for dependency names)\n const depMatches = content.matchAll(/\"([a-zA-Z0-9_-]+)\"/g);\n\n for (const match of depMatches) {\n if (match[1] !== undefined) {\n const name = match[1].toLowerCase();\n deps.set(name, { name, isDev: false, language: 'python' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read Cargo.toml (Rust)\n const cargoPath = join(projectRoot, 'Cargo.toml');\n if (existsSync(cargoPath)) {\n try {\n const content = await readFile(cargoPath, 'utf-8');\n // Match [dependencies] section entries like: serde = \"1.0\"\n // or serde = { version = \"1.0\", features = [...] }\n const inDepsSection = /\\[dependencies\\]([\\s\\S]*?)(?=\\n\\[|$)/;\n const depsMatch = inDepsSection.exec(content);\n if (depsMatch?.[1] !== undefined) {\n const depsSection = depsMatch[1];\n // Match crate names at start of lines\n const cratePattern = /^([a-zA-Z0-9_-]+)\\s*=/gm;\n for (const match of depsSection.matchAll(cratePattern)) {\n if (match[1] !== undefined) {\n deps.set(match[1], { name: match[1], isDev: false, language: 'rust' });\n }\n }\n }\n\n // Also check [dev-dependencies]\n const inDevDepsSection = /\\[dev-dependencies\\]([\\s\\S]*?)(?=\\n\\[|$)/;\n const devDepsMatch = inDevDepsSection.exec(content);\n if (devDepsMatch?.[1] !== undefined) {\n const devDepsSection = devDepsMatch[1];\n const cratePattern = /^([a-zA-Z0-9_-]+)\\s*=/gm;\n for (const match of devDepsSection.matchAll(cratePattern)) {\n if (match[1] !== undefined) {\n deps.set(match[1], { name: match[1], isDev: true, language: 'rust' });\n }\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Read go.mod (Go)\n const goModPath = join(projectRoot, 'go.mod');\n if (existsSync(goModPath)) {\n try {\n const content = await readFile(goModPath, 'utf-8');\n // Match require blocks and single requires\n // require github.com/gorilla/mux v1.8.0\n // require (\n // github.com/gorilla/mux v1.8.0\n // )\n const requirePattern = /^\\s*([a-zA-Z0-9._/-]+)\\s+v[\\d.]+/gm;\n for (const match of content.matchAll(requirePattern)) {\n if (match[1] !== undefined && !match[1].startsWith('//')) {\n // Go modules use the full path as the name\n deps.set(match[1], { name: match[1], isDev: false, language: 'go' });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n return deps;\n }\n}\n","export interface RepoSearchResult {\n url: string | null;\n confidence: 'high' | 'medium' | 'low';\n source: 'registry' | 'search' | 'fallback';\n}\n\n/**\n * Type guard to check if a value is a non-null object\n */\nfunction isObject(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport type SupportedLanguage = 'javascript' | 'python' | 'rust' | 'go';\n\nexport class RepoUrlResolver {\n /**\n * Find the GitHub repository URL for a package\n */\n async findRepoUrl(\n packageName: string,\n language: SupportedLanguage = 'javascript'\n ): Promise<RepoSearchResult> {\n // Strategy 1: Try package registry API (fast, accurate)\n let registryUrl: string | null = null;\n\n switch (language) {\n case 'javascript':\n registryUrl = await this.tryNpmRegistry(packageName);\n break;\n case 'python':\n registryUrl = await this.tryPyPiRegistry(packageName);\n break;\n case 'rust':\n registryUrl = await this.tryCratesRegistry(packageName);\n break;\n case 'go':\n registryUrl = await this.tryGoModule(packageName);\n break;\n }\n\n if (registryUrl !== null) {\n return { url: registryUrl, confidence: 'high', source: 'registry' };\n }\n\n // Strategy 2: No URL found\n return { url: null, confidence: 'low', source: 'fallback' };\n }\n\n /**\n * Query NPM registry for package metadata\n */\n private async tryNpmRegistry(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}`);\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL - safely access nested property\n if ('repository' in data) {\n const repo = data['repository'];\n if (isObject(repo) && 'url' in repo) {\n const urlValue = repo['url'];\n const url = String(urlValue);\n return this.normalizeRepoUrl(url);\n }\n\n if (typeof repo === 'string') {\n return this.normalizeRepoUrl(repo);\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Query PyPI registry for package metadata\n */\n private async tryPyPiRegistry(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://pypi.org/pypi/${packageName}/json`);\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL from project URLs\n if ('info' in data) {\n const info = data['info'];\n if (isObject(info) && 'project_urls' in info) {\n const projectUrls = info['project_urls'];\n\n if (isObject(projectUrls)) {\n // Try various common keys\n const urlKeys = ['Source', 'Repository', 'Code', 'Homepage'];\n\n for (const key of urlKeys) {\n if (key in projectUrls) {\n const urlValue = projectUrls[key];\n const url = String(urlValue);\n if (url.includes('github.com')) {\n return this.normalizeRepoUrl(url);\n }\n }\n }\n }\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Query crates.io registry for Rust crate metadata\n */\n private async tryCratesRegistry(crateName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://crates.io/api/v1/crates/${crateName}`, {\n headers: {\n // crates.io requires a User-Agent header\n 'User-Agent': 'bluera-knowledge (https://github.com/blueraai/bluera-knowledge)',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n const data: unknown = await response.json();\n if (!isObject(data)) {\n return null;\n }\n\n // Extract repository URL from crate metadata\n if ('crate' in data) {\n const crate = data['crate'];\n if (isObject(crate) && 'repository' in crate) {\n const repo = crate['repository'];\n if (typeof repo === 'string') {\n return this.normalizeRepoUrl(repo);\n }\n }\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve Go module to GitHub repository\n * Go modules often use GitHub URLs directly (e.g., github.com/gorilla/mux)\n */\n private async tryGoModule(moduleName: string): Promise<string | null> {\n try {\n // Go modules that start with github.com are already GitHub URLs\n if (moduleName.startsWith('github.com/')) {\n // Extract owner/repo from module path (e.g., github.com/gorilla/mux/v2 -> github.com/gorilla/mux)\n const parts = moduleName.split('/');\n const owner = parts[1];\n const repo = parts[2];\n if (owner !== undefined && repo !== undefined) {\n return `https://github.com/${owner}/${repo}`;\n }\n }\n\n // For other modules, try pkg.go.dev API\n // The pkg.go.dev API returns module info including repository URL\n const response = await fetch(`https://proxy.golang.org/${moduleName}/@latest`, {\n headers: {\n 'User-Agent': 'bluera-knowledge (https://github.com/blueraai/bluera-knowledge)',\n },\n });\n\n if (!response.ok) {\n return null;\n }\n\n // The Go proxy returns module info, but repository URL needs to be inferred\n // from the module path or VCS info. For now, we only support direct GitHub modules.\n // Most popular Go packages use github.com paths anyway.\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Normalize various repository URL formats to standard GitHub URL\n */\n private normalizeRepoUrl(url: string): string | null {\n // Remove git+ prefix\n let normalized = url.replace(/^git\\+/, '');\n\n // Remove .git suffix\n normalized = normalized.replace(/\\.git$/, '');\n\n // Convert git:// to https://\n normalized = normalized.replace(/^git:\\/\\//, 'https://');\n\n // Convert ssh:// to https://\n normalized = normalized.replace(/^ssh:\\/\\/git@/, 'https://');\n\n // Convert git@github.com: to https://github.com/\n normalized = normalized.replace(/^git@github\\.com:/, 'https://github.com/');\n\n // Only return if it's a GitHub URL\n if (normalized.includes('github.com')) {\n return normalized;\n }\n\n return null;\n }\n}\n","import { Command } from 'commander';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { SearchMode, DetailLevel } from '../../types/search.js';\nimport type { GlobalOptions } from '../program.js';\n\nexport function createSearchCommand(getOptions: () => GlobalOptions): Command {\n const search = new Command('search')\n .description('Search indexed documents using vector similarity + full-text matching')\n .argument('<query>', 'Search query')\n .option(\n '-s, --stores <stores>',\n 'Limit search to specific stores (comma-separated IDs or names)'\n )\n .option(\n '-m, --mode <mode>',\n 'vector (embeddings only), fts (text only), hybrid (both, default)',\n 'hybrid'\n )\n .option('-n, --limit <count>', 'Maximum results to return (default: 10)', '10')\n .option('-t, --threshold <score>', 'Minimum score 0-1; omit low-relevance results')\n .option(\n '--min-relevance <score>',\n 'Minimum raw cosine similarity 0-1; returns empty if no results meet threshold'\n )\n .option(\n '--detail <level>',\n 'Context detail: minimal, contextual, full (default: minimal)',\n 'minimal'\n )\n .action(\n async (\n query: string,\n options: {\n stores?: string;\n mode: SearchMode;\n limit: string;\n threshold?: string;\n minRelevance?: string;\n detail: DetailLevel;\n }\n ) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n // Get store IDs\n let storeIds = (await services.store.list()).map((s) => s.id);\n\n searchLogic: {\n if (options.stores !== undefined) {\n const requestedStores = options.stores.split(',').map((s) => s.trim());\n const resolvedStores = [];\n\n for (const requested of requestedStores) {\n const store = await services.store.getByIdOrName(requested);\n if (store !== undefined) {\n resolvedStores.push(store.id);\n } else {\n console.error(`Error: Store not found: ${requested}`);\n exitCode = 3;\n\n break searchLogic;\n }\n }\n\n storeIds = resolvedStores;\n }\n\n if (storeIds.length === 0) {\n console.error('No stores to search. Create a store first.');\n exitCode = 1;\n\n break searchLogic;\n }\n\n // Initialize LanceDB for each store\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const storeId of storeIds) {\n await services.lance.initialize(storeId);\n }\n\n // Validate numeric options\n const limit = parseInt(options.limit, 10);\n if (Number.isNaN(limit)) {\n throw new Error(\n `Invalid value for --limit: \"${options.limit}\" is not a valid integer`\n );\n }\n\n let threshold: number | undefined;\n if (options.threshold !== undefined) {\n threshold = parseFloat(options.threshold);\n if (Number.isNaN(threshold)) {\n throw new Error(\n `Invalid value for --threshold: \"${options.threshold}\" is not a valid number`\n );\n }\n if (threshold < 0 || threshold > 1) {\n throw new Error(`Invalid value for --threshold: must be between 0 and 1`);\n }\n }\n\n let minRelevance: number | undefined;\n if (options.minRelevance !== undefined) {\n minRelevance = parseFloat(options.minRelevance);\n if (Number.isNaN(minRelevance)) {\n throw new Error(\n `Invalid value for --min-relevance: \"${options.minRelevance}\" is not a valid number`\n );\n }\n if (minRelevance < 0 || minRelevance > 1) {\n throw new Error(`Invalid value for --min-relevance: must be between 0 and 1`);\n }\n }\n\n const results = await services.search.search({\n query,\n stores: storeIds,\n mode: options.mode,\n limit,\n threshold,\n minRelevance,\n detail: options.detail,\n });\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(results, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: just list matching paths/URLs, one per line\n for (const r of results.results) {\n const path = r.metadata.path ?? r.metadata.url ?? 'unknown';\n console.log(path);\n }\n } else {\n console.log(`\\nSearch: \"${query}\"`);\n\n // Build status line with optional confidence info\n let statusLine = `Mode: ${results.mode} | Detail: ${options.detail} | Stores: ${String(results.stores.length)} | Results: ${String(results.totalResults)} | Time: ${String(results.timeMs)}ms`;\n if (results.confidence !== undefined) {\n statusLine += ` | Confidence: ${results.confidence}`;\n }\n if (results.maxRawScore !== undefined) {\n statusLine += ` | MaxRaw: ${results.maxRawScore.toFixed(3)}`;\n }\n if (results.rerankTimeMs !== undefined) {\n statusLine += ` | Rerank: ${String(results.rerankTimeMs)}ms`;\n }\n console.log(`${statusLine}\\n`);\n\n if (results.results.length === 0) {\n if (results.confidence === 'low') {\n console.log('No sufficiently relevant results found.\\n');\n } else {\n console.log('No results found.\\n');\n }\n } else {\n for (let i = 0; i < results.results.length; i++) {\n const r = results.results[i];\n if (r === undefined) continue;\n\n if (r.summary) {\n console.log(\n `${String(i + 1)}. [${r.score.toFixed(2)}] ${r.summary.type}: ${r.summary.name}`\n );\n console.log(` ${r.summary.location}`);\n console.log(` ${r.summary.purpose}`);\n\n // Contextual: Show imports, concepts, and usage stats\n if (r.context && options.detail !== 'minimal') {\n if (r.context.keyImports.length > 0) {\n console.log(` Imports: ${r.context.keyImports.slice(0, 3).join(', ')}`);\n }\n if (r.context.relatedConcepts.length > 0) {\n console.log(\n ` Related: ${r.context.relatedConcepts.slice(0, 3).join(', ')}`\n );\n }\n // Show usage stats from code graph\n const { calledBy, calls } = r.context.usage;\n if (calledBy > 0 || calls > 0) {\n console.log(\n ` Usage: Called by ${String(calledBy)} | Calls ${String(calls)}`\n );\n }\n }\n\n // Full: Show complete code and documentation\n if (r.full && options.detail === 'full') {\n if (r.full.completeCode) {\n console.log(` ---`);\n const codeLines = r.full.completeCode.split('\\n');\n console.log(` ${codeLines.slice(0, 10).join('\\n ')}`);\n if (codeLines.length > 10) {\n console.log(` ... (truncated)`);\n }\n }\n if (r.full.documentation) {\n console.log(` Doc: ${r.full.documentation.slice(0, 100)}`);\n }\n }\n\n console.log();\n } else {\n // Display without summary\n const path = r.metadata.path ?? r.metadata.url ?? 'unknown';\n console.log(`${String(i + 1)}. [${r.score.toFixed(2)}] ${path}`);\n const preview =\n r.highlight ??\n r.content.slice(0, 150).replace(/\\n/g, ' ') +\n (r.content.length > 150 ? '...' : '');\n console.log(` ${preview}\\n`);\n }\n }\n }\n }\n }\n } finally {\n await destroyServices(services);\n }\n\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n\n return search;\n}\n","import { exec } from 'node:child_process';\nimport { platform } from 'node:os';\nimport { serve } from '@hono/node-server';\nimport { Command } from 'commander';\nimport { createApp } from '../../server/app.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { GlobalOptions } from '../program.js';\nimport type { ServerType } from '@hono/node-server';\nimport type { AddressInfo } from 'node:net';\n\n/**\n * Start the Hono server, trying the preferred port first.\n * If the preferred port is in use, falls back to an OS-assigned free port.\n * Uses the `serve` callback's `AddressInfo` to report the actual bound port.\n */\nexport function startServer(\n fetch: Parameters<typeof serve>[0]['fetch'],\n preferredPort: number,\n host: string\n): Promise<{ server: ServerType; port: number }> {\n return new Promise((resolve, reject) => {\n const server = serve({ fetch, port: preferredPort, hostname: host }, (info: AddressInfo) => {\n resolve({ server, port: info.port });\n });\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Preferred port taken — let the OS pick a free one\n const retryServer = serve({ fetch, port: 0, hostname: host }, (info: AddressInfo) => {\n resolve({ server: retryServer, port: info.port });\n });\n retryServer.on('error', reject);\n } else {\n reject(err);\n }\n });\n });\n}\n\nexport function createServeCommand(getOptions: () => GlobalOptions): Command {\n return new Command('serve')\n .description('Start HTTP API server for programmatic search access')\n .option('-p, --port <port>', 'Port to listen on (reads from config if not specified)')\n .option(\n '--host <host>',\n 'Bind address (reads from config if not specified, use 0.0.0.0 for all interfaces)'\n )\n .option('--open', 'Open the admin UI in the default browser after starting')\n .action(async (options: { port?: string; host?: string; open?: boolean }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n\n // Load config for defaults\n const appConfig = await services.config.load();\n const app = createApp(services);\n\n // Use config defaults, CLI flags override\n let preferredPort: number;\n if (options.port !== undefined) {\n preferredPort = parseInt(options.port, 10);\n if (Number.isNaN(preferredPort)) {\n throw new Error(`Invalid value for --port: \"${options.port}\" is not a valid integer`);\n }\n } else {\n preferredPort = appConfig.server.port;\n }\n const host = options.host ?? appConfig.server.host;\n\n const { server, port } = await startServer(app.fetch, preferredPort, host);\n if (port !== preferredPort) {\n console.log(`Port ${String(preferredPort)} in use, using ${String(port)}`);\n }\n const url = `http://${host}:${String(port)}`;\n console.log(`Starting server on ${url}`);\n\n if (options.open === true) {\n const openCmd =\n platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'start' : 'xdg-open';\n exec(`${openCmd} ${url}`);\n }\n\n // Graceful shutdown: close HTTP server, then cleanup services.\n // Do NOT call process.exit() - let the event loop drain naturally\n // so native code (lancedb, ONNX) can clean up without mutex corruption.\n let shuttingDown = false;\n const shutdown = (): void => {\n if (shuttingDown) return; // Prevent double-shutdown\n shuttingDown = true;\n server.close(() => {\n void destroyServices(services);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n}\n","import { rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { z } from 'zod';\nimport { JobService } from '../services/job.service.js';\nimport { spawnBackgroundWorker } from '../workers/spawn-worker.js';\nimport { renderAdminUI } from './ui/admin.js';\nimport type { ServiceContainer } from '../services/index.js';\nimport type { SearchQuery } from '../types/search.js';\n\n// HTTP API validation schemas (consistent with MCP schemas)\nconst CreateStoreBodySchema = z\n .object({\n name: z.string().min(1, 'Store name must be a non-empty string'),\n type: z.enum(['file', 'repo', 'web']),\n path: z.string().min(1).optional(),\n url: z.string().min(1).optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n branch: z.string().optional(),\n depth: z.number().int().positive().optional(),\n })\n .refine(\n (data) => {\n switch (data.type) {\n case 'file':\n return data.path !== undefined;\n case 'web':\n return data.url !== undefined;\n case 'repo':\n return data.path !== undefined || data.url !== undefined;\n }\n },\n {\n message:\n 'Missing required field: file stores need path, web stores need url, repo stores need path or url',\n }\n );\n\nconst SearchBodySchema = z.object({\n query: z.string().min(1, 'Query must be a non-empty string'),\n detail: z.enum(['minimal', 'contextual', 'full']).optional(),\n limit: z.number().int().positive().optional(),\n stores: z.array(z.string()).optional(),\n});\n\nexport function createApp(services: ServiceContainer): Hono {\n const app = new Hono();\n\n app.use('*', cors());\n\n // Admin UI\n app.get('/', (c) => c.html(renderAdminUI()));\n\n // Health check\n app.get('/health', (c) => c.json({ status: 'ok' }));\n\n // Stores\n app.get('/api/stores', async (c) => {\n const stores = await services.store.list();\n return c.json(stores);\n });\n\n app.post('/api/stores', async (c) => {\n const jsonData: unknown = await c.req.json();\n const parseResult = CreateStoreBodySchema.safeParse(jsonData);\n if (!parseResult.success) {\n return c.json({ error: parseResult.error.issues[0]?.message ?? 'Invalid request body' }, 400);\n }\n const result = await services.store.create(parseResult.data);\n if (!result.success) {\n return c.json({ error: result.error.message }, 400);\n }\n\n // Spawn background indexing — mirrors MCP handler behavior\n const dataDir = services.config.resolveDataDir();\n const isUrl = parseResult.data.url !== undefined;\n const jobType =\n parseResult.data.type === 'web'\n ? 'crawl'\n : parseResult.data.type === 'repo' && isUrl\n ? 'clone'\n : 'index';\n\n const storePath = result.data.type !== 'web' ? result.data.path : undefined;\n const jobDetails: Record<string, unknown> = {\n storeName: result.data.name,\n storeId: result.data.id,\n ...(isUrl ? { url: parseResult.data.url } : {}),\n ...(storePath !== undefined ? { path: storePath } : {}),\n phase: jobType === 'crawl' ? 'crawling' : jobType === 'clone' ? 'cloning' : 'indexing',\n phaseStep: 1,\n phaseTotalSteps: jobType === 'index' ? 1 : 2,\n };\n\n const jobService = new JobService(dataDir);\n const job = jobService.createJob({\n type: jobType,\n details: jobDetails,\n message: `${jobType === 'crawl' ? 'Crawling' : 'Indexing'} ${result.data.name}...`,\n });\n spawnBackgroundWorker(job.id, dataDir);\n\n return c.json({ ...result.data, job: { id: job.id, status: job.status } }, 201);\n });\n\n app.get('/api/stores/:id', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n return c.json(store);\n });\n\n app.delete('/api/stores/:id', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n\n // Delete LanceDB table first (so searches don't return results for deleted store)\n await services.lance.deleteStore(store.id);\n\n // Delete code graph\n await services.codeGraph.deleteGraph(store.id);\n\n // Delete manifest\n await services.manifest.delete(store.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n // Only delete if path is within our data directory (cloned repos)\n const resolvedDataDir = services.config.resolveDataDir();\n if (\n store.type === 'repo' &&\n 'url' in store &&\n store.url !== undefined &&\n store.path.startsWith(join(resolvedDataDir, 'repos'))\n ) {\n await rm(store.path, { recursive: true, force: true });\n }\n\n // Delete from registry last\n const result = await services.store.delete(store.id);\n if (result.success) return c.json({ deleted: true });\n return c.json({ error: result.error.message }, 400);\n });\n\n // Search\n app.post('/api/search', async (c) => {\n const jsonData: unknown = await c.req.json();\n const parseResult = SearchBodySchema.safeParse(jsonData);\n if (!parseResult.success) {\n return c.json({ error: parseResult.error.issues[0]?.message ?? 'Invalid request body' }, 400);\n }\n\n const storeIds = (await services.store.list()).map((s) => s.id);\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n for (const id of storeIds) {\n await services.lance.initialize(id);\n }\n\n // Resolve user-provided store strings to StoreIds, or use all stores\n let requestedStores = storeIds;\n if (parseResult.data.stores !== undefined) {\n const resolvedStores: typeof storeIds = [];\n for (const requested of parseResult.data.stores) {\n const store = await services.store.getByIdOrName(requested);\n if (store === undefined) {\n return c.json({ error: `Store not found: ${requested}` }, 404);\n }\n resolvedStores.push(store.id);\n }\n requestedStores = resolvedStores;\n }\n\n const query: SearchQuery = {\n query: parseResult.data.query,\n detail: parseResult.data.detail ?? 'minimal',\n limit: parseResult.data.limit ?? 10,\n stores: requestedStores,\n };\n const results = await services.search.search(query);\n return c.json(results);\n });\n\n // Documents (chunks) for a store\n app.get('/api/stores/:id/documents', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n\n const limit = parseInt(c.req.query('limit') ?? '50', 10);\n const offset = parseInt(c.req.query('offset') ?? '0', 10);\n\n try {\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const count = await services.lance.countDocuments(store.id);\n const documents = await services.lance.getAllDocuments(store.id, { limit, offset });\n return c.json({ documents, total: count, limit, offset });\n } catch {\n // Store may not be indexed yet\n return c.json({ documents: [], total: 0, limit, offset });\n }\n });\n\n // Index\n app.post('/api/stores/:id/index', async (c) => {\n const store = await services.store.getByIdOrName(c.req.param('id'));\n if (!store) return c.json({ error: 'Not found' }, 404);\n\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const result = await services.index.indexStore(store);\n\n if (result.success) return c.json(result.data);\n return c.json({ error: result.error.message }, 400);\n });\n\n // Jobs\n app.get('/api/jobs', (c) => {\n const dataDir = services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n return c.json(jobService.listJobs());\n });\n\n app.get('/api/jobs/:id', (c) => {\n const dataDir = services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n const job = jobService.getJob(c.req.param('id'));\n if (!job) return c.json({ error: 'Not found' }, 404);\n return c.json(job);\n });\n\n return app;\n}\n","/**\n * Admin SPA for bluera-knowledge.\n *\n * Self-contained HTML with inline CSS and JS. No external dependencies.\n * Uses hash-based routing for navigation between views.\n */\n\nimport { BASE_STYLES } from '../../mcp/ui/styles.js';\n\nconst ADMIN_STYLES = `\n /* ─── Layout ─── */\n body { margin: 0; }\n #app { display: flex; flex-direction: column; height: 100vh; }\n\n .app-shell { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n\n /* ─── Sidebar ─── */\n .sidebar {\n width: 220px;\n flex-shrink: 0;\n background: var(--bg-secondary);\n border-right: 1px solid var(--border-primary);\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n }\n\n .sidebar-brand {\n padding: var(--space-lg);\n border-bottom: 1px solid var(--border-secondary);\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n }\n\n .sidebar-brand-icon {\n width: 28px;\n height: 28px;\n border-radius: var(--radius-md);\n background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple));\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .sidebar-brand-text {\n font-size: var(--font-size-md);\n font-weight: 700;\n color: var(--text-primary);\n white-space: nowrap;\n }\n\n .sidebar-nav { padding: var(--space-sm); flex: 1; }\n\n .nav-item {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-md);\n border-radius: var(--radius-md);\n color: var(--text-secondary);\n text-decoration: none;\n font-size: var(--font-size-md);\n cursor: pointer;\n transition: background var(--transition-fast), color var(--transition-fast);\n border: none;\n background: none;\n width: 100%;\n text-align: left;\n font-family: var(--font-sans);\n }\n\n .nav-item:hover { background: var(--bg-tertiary); color: var(--text-primary); }\n .nav-item.active { background: rgba(88, 166, 255, 0.1); color: var(--accent-blue); }\n .nav-item svg { flex-shrink: 0; }\n\n .sidebar-footer {\n padding: var(--space-md) var(--space-lg);\n border-top: 1px solid var(--border-secondary);\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n }\n\n /* ─── Main Content ─── */\n .main-content {\n flex: 1;\n overflow-y: auto;\n padding: var(--space-xl) var(--space-2xl);\n min-width: 0;\n }\n\n .page-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--space-xl);\n flex-wrap: wrap;\n gap: var(--space-md);\n }\n\n .page-title {\n font-size: var(--font-size-2xl);\n font-weight: 700;\n color: var(--text-primary);\n }\n\n .page-subtitle {\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n margin-top: var(--space-xs);\n }\n\n /* ─── Breadcrumb ─── */\n .breadcrumb {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n font-size: var(--font-size-sm);\n color: var(--text-tertiary);\n margin-bottom: var(--space-lg);\n }\n\n .breadcrumb a {\n color: var(--text-link);\n text-decoration: none;\n cursor: pointer;\n }\n\n .breadcrumb a:hover { text-decoration: underline; }\n\n .breadcrumb-sep {\n color: var(--text-tertiary);\n margin: 0 var(--space-xs);\n }\n\n .breadcrumb-current { color: var(--text-secondary); }\n\n /* ─── Stats bar ─── */\n .stats-bar {\n display: flex;\n gap: var(--space-lg);\n margin-bottom: var(--space-xl);\n flex-wrap: wrap;\n }\n\n .stat-card {\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n padding: var(--space-md) var(--space-lg);\n display: flex;\n flex-direction: column;\n min-width: 100px;\n }\n\n .stat-value {\n font-size: var(--font-size-2xl);\n font-weight: 700;\n color: var(--text-primary);\n line-height: 1.2;\n }\n\n .stat-label {\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 2px;\n }\n\n /* ─── Store card grid ─── */\n .store-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n gap: var(--space-lg);\n }\n\n @media (max-width: 768px) {\n .store-grid { grid-template-columns: 1fr; }\n .sidebar { display: none; }\n .main-content { padding: var(--space-lg); }\n .stats-bar { flex-direction: column; }\n }\n\n .store-card {\n background: var(--bg-card);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n overflow: hidden;\n transition: border-color var(--transition-normal), box-shadow var(--transition-normal);\n display: flex;\n flex-direction: column;\n cursor: pointer;\n text-decoration: none;\n color: inherit;\n }\n\n .store-card:hover {\n border-color: rgba(88, 166, 255, 0.3);\n box-shadow: var(--shadow-md);\n background: var(--bg-card-hover);\n }\n\n .card-header {\n padding: var(--space-lg) var(--space-lg) var(--space-sm);\n }\n\n .card-title-row {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n }\n\n .card-status { display: flex; align-items: center; flex-shrink: 0; }\n\n .card-title {\n font-size: var(--font-size-md);\n font-weight: 600;\n color: var(--text-primary);\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .card-description {\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n margin-top: var(--space-sm);\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .card-body {\n padding: var(--space-sm) var(--space-lg);\n flex: 1;\n }\n\n .card-location {\n color: var(--text-tertiary);\n font-size: var(--font-size-sm);\n }\n\n .card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-xs);\n margin-top: var(--space-sm);\n }\n\n .card-footer {\n padding: var(--space-sm) var(--space-lg) var(--space-lg);\n border-top: 1px solid var(--border-secondary);\n margin-top: auto;\n }\n\n /* ─── Buttons ─── */\n .btn {\n display: inline-flex;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-lg);\n border-radius: var(--radius-md);\n font-size: var(--font-size-md);\n font-weight: 500;\n font-family: var(--font-sans);\n cursor: pointer;\n border: 1px solid transparent;\n transition: background var(--transition-fast), border-color var(--transition-fast), opacity var(--transition-fast);\n white-space: nowrap;\n text-decoration: none;\n }\n\n .btn:disabled { opacity: 0.5; cursor: not-allowed; }\n\n .btn-primary {\n background: var(--accent-blue);\n color: var(--text-inverse);\n border-color: var(--accent-blue);\n }\n .btn-primary:hover:not(:disabled) { opacity: 0.9; }\n\n .btn-secondary {\n background: var(--bg-tertiary);\n color: var(--text-primary);\n border-color: var(--border-primary);\n }\n .btn-secondary:hover:not(:disabled) { background: var(--bg-card-hover); }\n\n .btn-danger {\n background: rgba(248, 81, 73, 0.15);\n color: var(--accent-red);\n border-color: rgba(248, 81, 73, 0.3);\n }\n .btn-danger:hover:not(:disabled) { background: rgba(248, 81, 73, 0.25); }\n\n .btn-sm {\n padding: var(--space-xs) var(--space-md);\n font-size: var(--font-size-sm);\n }\n\n .btn-group {\n display: flex;\n gap: var(--space-sm);\n flex-wrap: wrap;\n }\n\n /* ─── Forms ─── */\n .form-group {\n margin-bottom: var(--space-lg);\n }\n\n .form-label {\n display: block;\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--text-primary);\n margin-bottom: var(--space-xs);\n }\n\n .form-hint {\n font-size: var(--font-size-xs);\n color: var(--text-tertiary);\n margin-top: var(--space-xs);\n }\n\n .form-input, .form-select, .form-textarea {\n width: 100%;\n padding: var(--space-sm) var(--space-md);\n background: var(--bg-inset);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-md);\n color: var(--text-primary);\n font-size: var(--font-size-md);\n font-family: var(--font-sans);\n transition: border-color var(--transition-fast);\n outline: none;\n }\n\n .form-input:focus, .form-select:focus, .form-textarea:focus {\n border-color: var(--accent-blue);\n box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.2);\n }\n\n .form-select {\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='%238b949e'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n padding-right: 32px;\n cursor: pointer;\n }\n\n .form-select option { background: var(--bg-secondary); color: var(--text-primary); }\n\n .form-textarea { resize: vertical; min-height: 80px; }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--space-lg);\n }\n\n @media (max-width: 640px) {\n .form-row { grid-template-columns: 1fr; }\n }\n\n .form-card {\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n padding: var(--space-xl);\n max-width: 640px;\n }\n\n .form-error {\n color: var(--accent-red);\n font-size: var(--font-size-sm);\n margin-top: var(--space-sm);\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n }\n\n /* ─── Store Detail ─── */\n .detail-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: var(--space-lg);\n margin-bottom: var(--space-xl);\n }\n\n @media (max-width: 768px) {\n .detail-grid { grid-template-columns: 1fr; }\n }\n\n .detail-card {\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n padding: var(--space-xl);\n }\n\n .detail-card-full {\n grid-column: 1 / -1;\n }\n\n .detail-row {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: var(--space-sm) 0;\n border-bottom: 1px solid var(--border-secondary);\n }\n\n .detail-row:last-child { border-bottom: none; }\n\n .detail-key {\n font-size: var(--font-size-sm);\n color: var(--text-tertiary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n flex-shrink: 0;\n min-width: 110px;\n }\n\n .detail-value {\n font-size: var(--font-size-sm);\n color: var(--text-primary);\n text-align: right;\n word-break: break-all;\n max-width: 70%;\n }\n\n /* ─── Search ─── */\n .search-bar {\n display: flex;\n gap: var(--space-sm);\n margin-bottom: var(--space-lg);\n }\n\n .search-bar .form-input {\n flex: 1;\n }\n\n .search-options {\n display: flex;\n gap: var(--space-lg);\n margin-bottom: var(--space-lg);\n flex-wrap: wrap;\n align-items: flex-end;\n }\n\n .search-option { min-width: 160px; }\n\n .search-meta-bar {\n display: flex;\n align-items: center;\n gap: var(--space-md);\n flex-wrap: wrap;\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n margin-bottom: var(--space-lg);\n padding: var(--space-md) var(--space-lg);\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n }\n\n .confidence-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 9999px;\n font-size: var(--font-size-xs);\n font-weight: 500;\n text-transform: capitalize;\n }\n\n .confidence-high { background: var(--confidence-high-bg); color: var(--confidence-high-text); }\n .confidence-medium { background: var(--confidence-medium-bg); color: var(--confidence-medium-text); }\n .confidence-low { background: var(--confidence-low-bg); color: var(--confidence-low-text); }\n\n /* ─── Results list ─── */\n .results-list {\n display: flex;\n flex-direction: column;\n gap: var(--space-md);\n }\n\n .result-card {\n background: var(--bg-card);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n overflow: hidden;\n transition: border-color var(--transition-normal);\n }\n\n .result-card:hover { border-color: rgba(88, 166, 255, 0.3); }\n\n .result-header {\n display: flex;\n gap: var(--space-md);\n padding: var(--space-lg);\n }\n\n .result-rank {\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--bg-tertiary);\n border: 1px solid var(--border-secondary);\n border-radius: var(--radius-sm);\n font-size: var(--font-size-sm);\n font-weight: 600;\n color: var(--text-tertiary);\n font-family: var(--font-mono);\n }\n\n .result-main { flex: 1; min-width: 0; }\n\n .result-title-row {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n margin-bottom: var(--space-xs);\n }\n\n .type-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: var(--radius-sm);\n font-size: 11px;\n font-weight: 700;\n font-family: var(--font-mono);\n flex-shrink: 0;\n }\n\n .type-fn { background: rgba(88, 166, 255, 0.15); color: var(--accent-blue); }\n .type-class { background: rgba(210, 153, 34, 0.15); color: var(--accent-orange); }\n .type-iface { background: rgba(57, 210, 192, 0.15); color: var(--accent-cyan); }\n .type-type { background: rgba(188, 140, 255, 0.15); color: var(--accent-purple); }\n .type-const { background: rgba(63, 185, 80, 0.15); color: var(--accent-green); }\n .type-doc { background: rgba(139, 148, 158, 0.15); color: var(--text-secondary); }\n .type-example { background: rgba(247, 120, 186, 0.15); color: var(--accent-pink); }\n .type-default { background: rgba(139, 148, 158, 0.1); color: var(--text-tertiary); }\n\n .result-name {\n font-size: var(--font-size-md);\n font-weight: 600;\n color: var(--text-primary);\n font-family: var(--font-mono);\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .result-signature {\n color: var(--text-secondary);\n margin-bottom: var(--space-sm);\n font-size: var(--font-size-sm);\n font-family: var(--font-mono);\n line-height: 1.4;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-all;\n }\n\n .result-purpose {\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n margin-bottom: var(--space-sm);\n line-height: 1.5;\n }\n\n .result-meta { margin-bottom: var(--space-xs); }\n\n .result-location {\n color: var(--text-tertiary);\n font-size: var(--font-size-sm);\n }\n\n .line-number { color: var(--accent-blue); }\n\n .result-store {\n font-size: var(--font-size-sm);\n color: var(--text-tertiary);\n }\n\n .result-relevance {\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n font-style: italic;\n margin-top: var(--space-xs);\n padding-left: var(--space-md);\n border-left: 2px solid var(--border-secondary);\n }\n\n .score-high { color: var(--score-high); }\n .score-medium { color: var(--score-medium); }\n .score-low { color: var(--score-low); }\n\n .result-card details { margin: 0; border-top: 1px solid var(--border-secondary); }\n .result-card details summary { padding: var(--space-sm) var(--space-lg); font-weight: 500; }\n .result-card .details-content { padding: 0 var(--space-lg) var(--space-lg); }\n\n .context-group, .full-group { margin-bottom: var(--space-md); }\n .context-group:last-child, .full-group:last-child { margin-bottom: 0; }\n\n .usage-stats { display: flex; gap: var(--space-lg); }\n .usage-stat { display: flex; align-items: baseline; gap: var(--space-xs); }\n .usage-value { font-size: var(--font-size-lg); font-weight: 700; font-family: var(--font-mono); color: var(--text-primary); }\n .usage-label { font-size: var(--font-size-xs); color: var(--text-tertiary); }\n\n .documentation-text {\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n line-height: 1.6;\n white-space: pre-wrap;\n }\n\n .result-card .code-block { max-height: 400px; overflow-y: auto; font-size: var(--font-size-sm); }\n\n .code-block::-webkit-scrollbar { width: 6px; height: 6px; }\n .code-block::-webkit-scrollbar-track { background: transparent; }\n .code-block::-webkit-scrollbar-thumb { background: var(--border-primary); border-radius: 3px; }\n .code-block::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }\n\n /* ─── Modal ─── */\n .modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n backdrop-filter: blur(4px);\n }\n\n .modal {\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-xl);\n padding: var(--space-xl);\n max-width: 420px;\n width: 90%;\n box-shadow: var(--shadow-lg);\n }\n\n .modal-title {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--text-primary);\n margin-bottom: var(--space-md);\n }\n\n .modal-body {\n font-size: var(--font-size-sm);\n color: var(--text-secondary);\n margin-bottom: var(--space-xl);\n line-height: 1.5;\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-sm);\n }\n\n /* ─── Toast ─── */\n .toast-container {\n position: fixed;\n top: var(--space-lg);\n right: var(--space-lg);\n z-index: 2000;\n display: flex;\n flex-direction: column;\n gap: var(--space-sm);\n pointer-events: none;\n }\n\n .toast {\n padding: var(--space-md) var(--space-lg);\n border-radius: var(--radius-lg);\n font-size: var(--font-size-sm);\n box-shadow: var(--shadow-lg);\n pointer-events: auto;\n animation: toast-in 300ms ease;\n max-width: 360px;\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n }\n\n .toast-error {\n background: rgba(248, 81, 73, 0.15);\n border: 1px solid rgba(248, 81, 73, 0.3);\n color: var(--accent-red);\n }\n\n .toast-success {\n background: rgba(63, 185, 80, 0.15);\n border: 1px solid rgba(63, 185, 80, 0.3);\n color: var(--accent-green);\n }\n\n .toast-info {\n background: rgba(88, 166, 255, 0.15);\n border: 1px solid rgba(88, 166, 255, 0.3);\n color: var(--accent-blue);\n }\n\n @keyframes toast-in {\n from { opacity: 0; transform: translateY(-12px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n /* ─── Spinner ─── */\n .spinner {\n width: 20px;\n height: 20px;\n border: 2px solid var(--border-primary);\n border-top-color: var(--accent-blue);\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n display: inline-block;\n flex-shrink: 0;\n }\n\n .spinner-lg { width: 32px; height: 32px; border-width: 3px; }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .loading-center {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-2xl);\n gap: var(--space-md);\n color: var(--text-secondary);\n font-size: var(--font-size-sm);\n }\n\n /* ─── Skeleton ─── */\n .skeleton {\n background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-card-hover) 50%, var(--bg-tertiary) 75%);\n background-size: 200% 100%;\n animation: skeleton-pulse 1.5s ease-in-out infinite;\n border-radius: var(--radius-md);\n }\n\n @keyframes skeleton-pulse {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n\n .skeleton-card {\n height: 180px;\n border-radius: var(--radius-lg);\n }\n\n .skeleton-line {\n height: 16px;\n margin-bottom: var(--space-sm);\n }\n\n .skeleton-line-short { width: 60%; }\n\n /* ─── Multi-select (store filter) ─── */\n .multi-select {\n position: relative;\n }\n\n .multi-select-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--space-sm) var(--space-md);\n background: var(--bg-inset);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-md);\n color: var(--text-primary);\n font-size: var(--font-size-md);\n cursor: pointer;\n min-height: 38px;\n font-family: var(--font-sans);\n }\n\n .multi-select-trigger:hover { border-color: var(--accent-blue); }\n\n .multi-select-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--bg-secondary);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-lg);\n z-index: 100;\n margin-top: var(--space-xs);\n max-height: 200px;\n overflow-y: auto;\n display: none;\n }\n\n .multi-select-dropdown.open { display: block; }\n\n .multi-select-option {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-sm) var(--space-md);\n cursor: pointer;\n font-size: var(--font-size-sm);\n color: var(--text-primary);\n transition: background var(--transition-fast);\n }\n\n .multi-select-option:hover { background: var(--bg-tertiary); }\n\n .multi-select-option input[type=\"checkbox\"] {\n accent-color: var(--accent-blue);\n }\n\n /* ─── Mobile nav toggle ─── */\n .mobile-nav-toggle {\n display: none;\n position: fixed;\n bottom: var(--space-lg);\n right: var(--space-lg);\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--accent-blue);\n color: var(--text-inverse);\n border: none;\n cursor: pointer;\n z-index: 500;\n box-shadow: var(--shadow-lg);\n align-items: center;\n justify-content: center;\n }\n\n @media (max-width: 768px) {\n .mobile-nav-toggle { display: flex; }\n .sidebar.mobile-open { display: flex; position: fixed; top: 0; left: 0; bottom: 0; z-index: 400; }\n }\n\n /* ─── Misc ─── */\n .inline-search-section {\n margin-top: var(--space-xl);\n padding-top: var(--space-xl);\n border-top: 1px solid var(--border-primary);\n }\n\n .section-title {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--text-primary);\n margin-bottom: var(--space-lg);\n }\n\n .store-actions {\n margin-bottom: var(--space-xl);\n }\n\n /* ─── Documents section ─── */\n .documents-section {\n margin-top: var(--space-xl);\n padding-top: var(--space-xl);\n border-top: 1px solid var(--border-primary);\n }\n\n .documents-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--space-lg);\n }\n\n .documents-list {\n display: flex;\n flex-direction: column;\n gap: var(--space-md);\n }\n\n .document-item {\n background: var(--bg-card);\n border: 1px solid var(--border-primary);\n border-radius: var(--radius-lg);\n overflow: hidden;\n transition: border-color var(--transition-normal);\n }\n\n .document-item:hover {\n border-color: rgba(88, 166, 255, 0.3);\n }\n\n .document-meta {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n padding: var(--space-md) var(--space-lg);\n background: var(--bg-tertiary);\n border-bottom: 1px solid var(--border-secondary);\n font-size: var(--font-size-sm);\n min-height: 40px;\n }\n\n .document-index {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n padding: 0 var(--space-xs);\n background: var(--bg-inset);\n border: 1px solid var(--border-secondary);\n border-radius: var(--radius-sm);\n font-size: var(--font-size-xs);\n font-family: var(--font-mono);\n color: var(--text-tertiary);\n flex-shrink: 0;\n }\n\n .document-path {\n color: var(--text-link);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: 500;\n }\n\n .document-chunk-label {\n color: var(--text-tertiary);\n font-size: var(--font-size-xs);\n white-space: nowrap;\n }\n\n .document-content {\n margin: 0;\n padding: var(--space-lg) !important;\n min-height: 80px;\n max-height: 300px;\n overflow-y: auto;\n font-size: var(--font-size-sm) !important;\n line-height: 1.7 !important;\n white-space: pre-wrap !important;\n word-break: break-word;\n border: none !important;\n border-radius: 0 !important;\n background: var(--bg-inset) !important;\n }\n\n .document-content::-webkit-scrollbar { width: 6px; }\n .document-content::-webkit-scrollbar-track { background: transparent; }\n .document-content::-webkit-scrollbar-thumb { background: var(--border-primary); border-radius: 3px; }\n .document-content::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }\n\n .documents-pagination {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-md);\n margin-top: var(--space-xl);\n padding: var(--space-lg) 0;\n border-top: 1px solid var(--border-secondary);\n }\n\n .btn-sm {\n padding: var(--space-xs) var(--space-md);\n font-size: var(--font-size-sm);\n }\n\n .text-secondary { color: var(--text-secondary); }\n .text-tertiary { color: var(--text-tertiary); }\n`;\n\nexport function renderAdminUI(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bluera Knowledge - Admin</title>\n <style>${BASE_STYLES}${ADMIN_STYLES}</style>\n</head>\n<body>\n <div id=\"app\"></div>\n <div class=\"toast-container\" id=\"toast-container\"></div>\n <div id=\"modal-root\"></div>\n <script>\n (function() {\n 'use strict';\n\n // ─── Utilities ───\n\n function esc(str) {\n if (str == null) return '';\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n\n function formatDate(iso) {\n if (!iso) return '';\n var d = new Date(iso);\n var now = new Date();\n var diffMs = now.getTime() - d.getTime();\n var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n if (diffDays === 0) return 'Today';\n if (diffDays === 1) return 'Yesterday';\n if (diffDays < 7) return diffDays + 'd ago';\n if (diffDays < 30) return Math.floor(diffDays / 7) + 'w ago';\n if (diffDays < 365) return Math.floor(diffDays / 30) + 'mo ago';\n return Math.floor(diffDays / 365) + 'y ago';\n }\n\n function formatFullDate(iso) {\n if (!iso) return '';\n return new Date(iso).toLocaleString();\n }\n\n // ─── SVG Icons ───\n\n var ICONS = {\n stores: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1h-8a1 1 0 00-1 1v6.708A2.486 2.486 0 014.5 9h8V1.5zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z\"/></svg>',\n search: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M10.68 11.74a6 6 0 01-7.922-8.982 6 6 0 018.982 7.922l3.04 3.04a.749.749 0 01-.326 1.275.749.749 0 01-.734-.215l-3.04-3.04zM11.5 7a4.499 4.499 0 10-8.997 0A4.499 4.499 0 0011.5 7z\"/></svg>',\n plus: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M7.75 2a.75.75 0 01.75.75V7h4.25a.75.75 0 010 1.5H8.5v4.25a.75.75 0 01-1.5 0V8.5H2.75a.75.75 0 010-1.5H7V2.75A.75.75 0 017.75 2z\"/></svg>',\n trash: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M6.5 1.75a.25.25 0 01.25-.25h2.5a.25.25 0 01.25.25V3h-3V1.75zm4.5 0V3h2.25a.75.75 0 010 1.5H2.75a.75.75 0 010-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75zM4.496 6.675a.75.75 0 10-1.492.15l.66 6.6A1.75 1.75 0 005.405 15h5.19a1.75 1.75 0 001.741-1.575l.66-6.6a.75.75 0 00-1.492-.15l-.66 6.6a.25.25 0 01-.249.225h-5.19a.25.25 0 01-.249-.225l-.66-6.6z\"/></svg>',\n refresh: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M8 2.5a5.487 5.487 0 00-4.131 1.869l1.204 1.204A.25.25 0 014.896 6H1.25A.25.25 0 011 5.75V2.104a.25.25 0 01.427-.177l1.38 1.38A7.001 7.001 0 0114.95 7.16a.75.75 0 11-1.49.178A5.501 5.501 0 008 2.5zM1.705 8.005a.75.75 0 01.834.656 5.501 5.501 0 009.592 2.97l-1.204-1.204a.25.25 0 01.177-.427h3.646a.25.25 0 01.25.25v3.646a.25.25 0 01-.427.177l-1.38-1.38A7.001 7.001 0 011.05 8.84a.75.75 0 01.656-.834z\"/></svg>',\n repo: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1h-8a1 1 0 00-1 1v6.708A2.486 2.486 0 014.5 9h8V1.5zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z\"/></svg>',\n file: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M3.75 1.5a.25.25 0 00-.25.25v11.5c0 .138.112.25.25.25h8.5a.25.25 0 00.25-.25V6H9.75A1.75 1.75 0 018 4.25V1.5H3.75zm5.75.56v2.19c0 .138.112.25.25.25h2.19L9.5 2.06zM2 1.75C2 .784 2.784 0 3.75 0h5.086c.464 0 .909.184 1.237.513l3.414 3.414c.329.328.513.773.513 1.237v8.086A1.75 1.75 0 0112.25 15h-8.5A1.75 1.75 0 012 13.25V1.75z\"/></svg>',\n web: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM6.379 5.227A31.17 31.17 0 006 7.5h4c-.07-.77-.2-1.53-.379-2.273a4.7 4.7 0 01-.862.22 4.5 4.5 0 01-1.038 0 4.7 4.7 0 01-.862-.22zM5.43 7.5c.05-.9.155-1.79.42-2.667a8.2 8.2 0 01-.987-.652A6.54 6.54 0 003.538 7.5H5.43zm-1.893 1.5h1.893c.05.898.155 1.787.42 2.667-.326.217-.668.41-.987.652A6.54 6.54 0 013.538 9zm6.963 0c-.05.898-.155 1.787-.42 2.667.326.217.668.41.987.652A6.54 6.54 0 0012.462 9h-1.893zm1.893-1.5h-1.893c-.05-.9-.155-1.79-.42-2.667.326-.217.668-.41.987-.652A6.54 6.54 0 0112.462 7.5zM6 9h4c-.07.77-.2 1.53-.379 2.273a4.7 4.7 0 01-.862-.22 4.5 4.5 0 01-1.038 0 4.7 4.7 0 01-.862.22A31.17 31.17 0 016 9z\"/></svg>',\n brand: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"white\"><path d=\"M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm6.5-2a1.5 1.5 0 113 0v4a1.5 1.5 0 01-3 0V6z\"/></svg>',\n hamburger: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M1 2.75A.75.75 0 011.75 2h12.5a.75.75 0 010 1.5H1.75A.75.75 0 011 2.75zm0 5A.75.75 0 011.75 7h12.5a.75.75 0 010 1.5H1.75A.75.75 0 011 7.75zM1.75 12h12.5a.75.75 0 010 1.5H1.75a.75.75 0 010-1.5z\"/></svg>',\n chevron: '<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"currentColor\"><path d=\"M4.7 2.3a.75.75 0 000 1.06L7.94 6.64 4.7 9.88a.75.75 0 101.06 1.06l3.87-3.87a.75.75 0 000-1.06L5.76 2.14a.75.75 0 00-1.06.16z\"/></svg>'\n };\n\n // ─── API client ───\n\n function api(method, path, body) {\n var opts = { method: method, headers: { 'Content-Type': 'application/json' } };\n if (body !== undefined) opts.body = JSON.stringify(body);\n return fetch(path, opts).then(function(res) {\n return res.json().then(function(data) {\n if (!res.ok) throw new Error(data.error || 'Request failed (' + res.status + ')');\n return data;\n });\n });\n }\n\n // ─── Toast notifications ───\n\n function showToast(message, type) {\n var container = document.getElementById('toast-container');\n var toast = document.createElement('div');\n toast.className = 'toast toast-' + (type || 'info');\n toast.textContent = message;\n container.appendChild(toast);\n setTimeout(function() {\n toast.style.transition = 'opacity 300ms';\n toast.style.opacity = '0';\n setTimeout(function() { toast.remove(); }, 300);\n }, 4000);\n }\n\n // ─── Modal ───\n\n function showModal(title, body, onConfirm, confirmLabel, confirmClass) {\n var root = document.getElementById('modal-root');\n root.innerHTML =\n '<div class=\"modal-overlay\" id=\"modal-overlay\">' +\n '<div class=\"modal\">' +\n '<div class=\"modal-title\">' + esc(title) + '</div>' +\n '<div class=\"modal-body\">' + esc(body) + '</div>' +\n '<div class=\"modal-actions\">' +\n '<button class=\"btn btn-secondary\" id=\"modal-cancel\">Cancel</button>' +\n '<button class=\"btn ' + (confirmClass || 'btn-danger') + '\" id=\"modal-confirm\">' + esc(confirmLabel || 'Confirm') + '</button>' +\n '</div>' +\n '</div>' +\n '</div>';\n document.getElementById('modal-cancel').onclick = function() { root.innerHTML = ''; };\n document.getElementById('modal-overlay').onclick = function(e) {\n if (e.target === e.currentTarget) root.innerHTML = '';\n };\n document.getElementById('modal-confirm').onclick = function() {\n root.innerHTML = '';\n onConfirm();\n };\n }\n\n function hideModal() {\n document.getElementById('modal-root').innerHTML = '';\n }\n\n // ─── State ───\n\n var state = {\n stores: [],\n storesLoaded: false,\n currentStore: null,\n searchResults: null,\n refreshTimer: null,\n mobileNavOpen: false\n };\n\n // ─── Type helpers ───\n\n function typeIcon(type) {\n switch (type) {\n case 'repo': return ICONS.repo;\n case 'file': return ICONS.file;\n case 'web': return ICONS.web;\n default: return '';\n }\n }\n\n function storeStatus(store) {\n if (store.status === 'indexing') return 'indexing';\n if (store.status === 'error') return 'error';\n if (store.modelId) return 'ready';\n return 'unknown';\n }\n\n function storeStatusLabel(store) {\n var s = storeStatus(store);\n switch (s) {\n case 'ready': return 'Ready';\n case 'indexing': return 'Indexing';\n case 'error': return 'Error';\n default: return 'Not indexed';\n }\n }\n\n function scoreColor(score) {\n if (score >= 0.7) return 'var(--score-high)';\n if (score >= 0.4) return 'var(--score-medium)';\n return 'var(--score-low)';\n }\n\n function scoreClass(score) {\n if (score >= 0.7) return 'high';\n if (score >= 0.4) return 'medium';\n return 'low';\n }\n\n function resultTypeIcon(type) {\n var map = {\n 'function': '<span class=\"type-icon type-fn\">fn</span>',\n 'class': '<span class=\"type-icon type-class\">C</span>',\n 'interface': '<span class=\"type-icon type-iface\">I</span>',\n 'type': '<span class=\"type-icon type-type\">T</span>',\n 'const': '<span class=\"type-icon type-const\">K</span>',\n 'documentation': '<span class=\"type-icon type-doc\">D</span>',\n 'example': '<span class=\"type-icon type-example\">E</span>'\n };\n return map[type] || '<span class=\"type-icon type-default\">?</span>';\n }\n\n // ─── Routing ───\n\n function navigate(hash) {\n window.location.hash = hash;\n }\n\n function getRoute() {\n var hash = window.location.hash || '#/';\n if (hash === '#/' || hash === '#/stores') return { view: 'dashboard' };\n var storeMatch = hash.match(/^#\\\\/stores\\\\/(.+)$/);\n if (storeMatch) return { view: 'detail', id: decodeURIComponent(storeMatch[1]) };\n if (hash === '#/create') return { view: 'create' };\n if (hash.startsWith('#/search')) {\n var params = new URLSearchParams(hash.replace('#/search', '').replace('?', ''));\n return { view: 'search', query: params.get('q') || '' };\n }\n return { view: 'dashboard' };\n }\n\n // ─── Rendering ───\n\n function renderApp() {\n clearInterval(state.refreshTimer);\n state.refreshTimer = null;\n\n var route = getRoute();\n var navActive = route.view;\n\n var html =\n '<div class=\"app-shell\">' +\n renderSidebar(navActive) +\n '<div class=\"main-content\" id=\"main-content\">' +\n renderLoading() +\n '</div>' +\n '</div>' +\n '<button class=\"mobile-nav-toggle\" id=\"mobile-nav-toggle\">' + ICONS.hamburger + '</button>';\n\n document.getElementById('app').innerHTML = html;\n\n document.getElementById('mobile-nav-toggle').onclick = function() {\n var sidebar = document.querySelector('.sidebar');\n state.mobileNavOpen = !state.mobileNavOpen;\n if (state.mobileNavOpen) {\n sidebar.classList.add('mobile-open');\n } else {\n sidebar.classList.remove('mobile-open');\n }\n };\n\n switch (route.view) {\n case 'dashboard': loadDashboard(); break;\n case 'detail': loadStoreDetail(route.id); break;\n case 'create': renderCreateStore(); break;\n case 'search': renderSearchView(route.query); break;\n default: loadDashboard();\n }\n }\n\n function renderSidebar(active) {\n return (\n '<div class=\"sidebar\">' +\n '<div class=\"sidebar-brand\">' +\n '<div class=\"sidebar-brand-icon\">' + ICONS.brand + '</div>' +\n '<span class=\"sidebar-brand-text\">Knowledge</span>' +\n '</div>' +\n '<nav class=\"sidebar-nav\">' +\n '<a class=\"nav-item' + (active === 'dashboard' ? ' active' : '') + '\" href=\"#/stores\">' +\n ICONS.stores + ' Stores' +\n '</a>' +\n '<a class=\"nav-item' + (active === 'search' ? ' active' : '') + '\" href=\"#/search\">' +\n ICONS.search + ' Search' +\n '</a>' +\n '<a class=\"nav-item' + (active === 'create' ? ' active' : '') + '\" href=\"#/create\">' +\n ICONS.plus + ' Create Store' +\n '</a>' +\n '</nav>' +\n '<div class=\"sidebar-footer\">Bluera Knowledge Admin</div>' +\n '</div>'\n );\n }\n\n function renderLoading() {\n return '<div class=\"loading-center\"><div class=\"spinner spinner-lg\"></div> Loading...</div>';\n }\n\n function renderSkeletonCards(n) {\n var html = '<div class=\"store-grid\">';\n for (var i = 0; i < n; i++) {\n html += '<div class=\"skeleton skeleton-card\"></div>';\n }\n html += '</div>';\n return html;\n }\n\n // ─── Dashboard ───\n\n function loadDashboard() {\n var main = document.getElementById('main-content');\n main.innerHTML = renderSkeletonCards(6);\n\n api('GET', '/api/stores').then(function(stores) {\n state.stores = stores;\n state.storesLoaded = true;\n renderDashboardContent();\n\n state.refreshTimer = setInterval(function() {\n api('GET', '/api/stores').then(function(s) {\n state.stores = s;\n if (getRoute().view === 'dashboard') renderDashboardContent();\n }).catch(function() {});\n }, 10000);\n }).catch(function(err) {\n main.innerHTML = '<div class=\"empty-state\"><div class=\"empty-state-title\">Failed to load stores</div><p>' + esc(err.message) + '</p></div>';\n });\n }\n\n function renderDashboardContent() {\n var main = document.getElementById('main-content');\n var stores = state.stores;\n\n var repoCount = 0, fileCount = 0, webCount = 0, indexedCount = 0;\n for (var i = 0; i < stores.length; i++) {\n if (stores[i].type === 'repo') repoCount++;\n if (stores[i].type === 'file') fileCount++;\n if (stores[i].type === 'web') webCount++;\n if (stores[i].modelId) indexedCount++;\n }\n\n var html =\n '<div class=\"page-header\">' +\n '<div>' +\n '<h1 class=\"page-title\">Knowledge Stores</h1>' +\n '<p class=\"page-subtitle\">' + stores.length + ' store' + (stores.length !== 1 ? 's' : '') + ' configured</p>' +\n '</div>' +\n '<a class=\"btn btn-primary\" href=\"#/create\">' + ICONS.plus + ' Create Store</a>' +\n '</div>' +\n '<div class=\"stats-bar\">' +\n renderStatCard(stores.length, 'Total') +\n renderStatCard(indexedCount, 'Indexed') +\n renderStatCard(stores.length - indexedCount, 'Pending') +\n (repoCount > 0 ? renderStatCard(repoCount, 'Repo') : '') +\n (fileCount > 0 ? renderStatCard(fileCount, 'File') : '') +\n (webCount > 0 ? renderStatCard(webCount, 'Web') : '') +\n '</div>';\n\n if (stores.length === 0) {\n html += '<div class=\"empty-state\"><div class=\"empty-state-title\">No knowledge stores</div><p>Create a store to start indexing code and documentation.</p></div>';\n } else {\n html += '<div class=\"store-grid\">';\n for (var j = 0; j < stores.length; j++) {\n html += renderStoreCard(stores[j]);\n }\n html += '</div>';\n }\n\n main.innerHTML = html;\n bindCardClicks();\n }\n\n function renderStatCard(value, label) {\n return (\n '<div class=\"stat-card\">' +\n '<span class=\"stat-value\">' + value + '</span>' +\n '<span class=\"stat-label\">' + esc(label) + '</span>' +\n '</div>'\n );\n }\n\n function renderStoreCard(store) {\n var st = storeStatus(store);\n var loc = store.path || store.url || '';\n var truncLoc = loc.length > 60 ? '...' + loc.slice(loc.length - 57) : loc;\n\n var tagsHtml = '';\n if (store.tags && store.tags.length > 0) {\n tagsHtml = '<div class=\"card-tags\">';\n for (var i = 0; i < store.tags.length; i++) {\n tagsHtml += '<span class=\"tag\">' + esc(store.tags[i]) + '</span>';\n }\n tagsHtml += '</div>';\n }\n\n var descHtml = store.description\n ? '<p class=\"card-description\">' + esc(store.description) + '</p>'\n : '';\n\n var branchHtml = store.branch\n ? '<span class=\"meta-separator\"></span><span class=\"mono\">' + esc(store.branch) + '</span>'\n : '';\n\n return (\n '<div class=\"store-card\" data-store-id=\"' + esc(store.id) + '\">' +\n '<div class=\"card-header\">' +\n '<div class=\"card-title-row\">' +\n '<div class=\"card-status\"><span class=\"status-dot status-' + st + '\" title=\"' + esc(storeStatusLabel(store)) + '\"></span></div>' +\n '<h3 class=\"card-title\">' + esc(store.name) + '</h3>' +\n '<span class=\"badge badge-' + store.type + '\">' + typeIcon(store.type) + '<span style=\"margin-left:4px\">' + store.type + '</span></span>' +\n '</div>' +\n descHtml +\n '</div>' +\n '<div class=\"card-body\">' +\n (loc ? '<div class=\"card-location mono truncate\" title=\"' + esc(loc) + '\">' + esc(truncLoc) + '</div>' : '') +\n tagsHtml +\n '</div>' +\n '<div class=\"card-footer\"><div class=\"meta-row\">' +\n '<span title=\"' + esc(store.createdAt) + '\">' + formatDate(store.createdAt) + '</span>' +\n branchHtml +\n '</div></div>' +\n '</div>'\n );\n }\n\n function bindCardClicks() {\n var cards = document.querySelectorAll('.store-card[data-store-id]');\n for (var i = 0; i < cards.length; i++) {\n (function(card) {\n card.onclick = function() {\n navigate('#/stores/' + encodeURIComponent(card.getAttribute('data-store-id')));\n };\n })(cards[i]);\n }\n }\n\n // ─── Store Detail ───\n\n function loadStoreDetail(id) {\n var main = document.getElementById('main-content');\n main.innerHTML = renderLoading();\n\n api('GET', '/api/stores/' + encodeURIComponent(id)).then(function(store) {\n state.currentStore = store;\n renderStoreDetailContent(store);\n }).catch(function(err) {\n main.innerHTML =\n '<div class=\"breadcrumb\"><a href=\"#/stores\">Stores</a><span class=\"breadcrumb-sep\">' + ICONS.chevron + '</span><span class=\"breadcrumb-current\">Not found</span></div>' +\n '<div class=\"empty-state\"><div class=\"empty-state-title\">Store not found</div><p>' + esc(err.message) + '</p></div>';\n });\n }\n\n function renderStoreDetailContent(store) {\n var main = document.getElementById('main-content');\n var st = storeStatus(store);\n\n var rows = [];\n\n // URL first for repo/web stores — externally linked\n if (store.url) rows.push({ key: 'URL', value: store.url, link: true });\n\n rows.push({ key: 'ID', value: store.id });\n rows.push({ key: 'Name', value: store.name });\n rows.push({ key: 'Type', value: store.type });\n rows.push({ key: 'Status', value: storeStatusLabel(store) });\n\n if (store.path) rows.push({ key: 'Path', value: store.path });\n if (store.branch) rows.push({ key: 'Branch', value: store.branch });\n if (store.depth != null) rows.push({ key: 'Depth', value: String(store.depth) });\n if (store.maxPages != null) rows.push({ key: 'Max Pages', value: String(store.maxPages) });\n if (store.modelId) rows.push({ key: 'Model', value: store.modelId });\n if (store.schemaVersion != null) rows.push({ key: 'Schema', value: 'v' + store.schemaVersion });\n rows.push({ key: 'Created', value: formatFullDate(store.createdAt) });\n rows.push({ key: 'Updated', value: formatFullDate(store.updatedAt) });\n\n var detailRows = '';\n for (var i = 0; i < rows.length; i++) {\n var val = rows[i].link\n ? '<a href=\"' + esc(rows[i].value) + '\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"color:var(--text-link);text-decoration:none\">' + esc(rows[i].value) + ' <span style=\"font-size:11px;opacity:0.6\">↗</span></a>'\n : esc(rows[i].value);\n detailRows += '<div class=\"detail-row\"><span class=\"detail-key\">' + esc(rows[i].key) + '</span><span class=\"detail-value mono\">' + val + '</span></div>';\n }\n\n var tagsHtml = '';\n if (store.tags && store.tags.length > 0) {\n tagsHtml = '<div class=\"detail-row\"><span class=\"detail-key\">Tags</span><span class=\"detail-value\"><div class=\"card-tags\">';\n for (var t = 0; t < store.tags.length; t++) {\n tagsHtml += '<span class=\"tag\">' + esc(store.tags[t]) + '</span>';\n }\n tagsHtml += '</div></span></div>';\n }\n\n var descHtml = '';\n if (store.description) {\n descHtml = '<div class=\"detail-row\"><span class=\"detail-key\">Description</span><span class=\"detail-value\" style=\"text-align:left;max-width:none;word-break:normal\">' + esc(store.description) + '</span></div>';\n }\n\n var html =\n '<div class=\"breadcrumb\">' +\n '<a href=\"#/stores\">Stores</a>' +\n '<span class=\"breadcrumb-sep\">' + ICONS.chevron + '</span>' +\n '<span class=\"breadcrumb-current\">' + esc(store.name) + '</span>' +\n '</div>' +\n '<div class=\"page-header\">' +\n '<div style=\"display:flex;align-items:center;gap:var(--space-md)\">' +\n '<span class=\"status-dot status-' + st + '\" style=\"width:12px;height:12px\" title=\"' + esc(storeStatusLabel(store)) + '\"></span>' +\n '<h1 class=\"page-title\">' + esc(store.name) + '</h1>' +\n '<span class=\"badge badge-' + store.type + '\">' + typeIcon(store.type) + '<span style=\"margin-left:4px\">' + store.type + '</span></span>' +\n '</div>' +\n '</div>' +\n '<div class=\"store-actions\"><div class=\"btn-group\">' +\n '<button class=\"btn btn-secondary\" id=\"btn-reindex\">' + ICONS.refresh + ' Re-index</button>' +\n '<button class=\"btn btn-danger\" id=\"btn-delete\">' + ICONS.trash + ' Delete</button>' +\n '</div></div>' +\n '<div class=\"detail-grid\">' +\n '<div class=\"detail-card\">' + detailRows + '</div>' +\n '<div class=\"detail-card\">' + descHtml + tagsHtml +\n ((!store.description && (!store.tags || store.tags.length === 0))\n ? '<div class=\"empty-state\" style=\"padding:var(--space-lg) 0\"><p>No description or tags</p></div>'\n : '') +\n '</div>' +\n '</div>' +\n '<div class=\"inline-search-section\">' +\n '<h2 class=\"section-title\">Search in ' + esc(store.name) + '</h2>' +\n '<div class=\"search-bar\">' +\n '<input class=\"form-input\" id=\"detail-search-input\" type=\"text\" placeholder=\"Search within this store...\" />' +\n '<button class=\"btn btn-primary\" id=\"detail-search-btn\">' + ICONS.search + ' Search</button>' +\n '</div>' +\n '<div id=\"detail-search-results\"></div>' +\n '</div>' +\n '<div class=\"documents-section\">' +\n '<h2 class=\"section-title\">Indexed Chunks</h2>' +\n '<div id=\"documents-container\"><div class=\"loading-center\"><div class=\"spinner\"></div> Loading chunks...</div></div>' +\n '</div>';\n\n main.innerHTML = html;\n\n // Load documents\n loadDocuments(store.id, 0);\n\n // Bind actions\n document.getElementById('btn-reindex').onclick = function() {\n var btn = this;\n btn.disabled = true;\n btn.innerHTML = '<div class=\"spinner\"></div> Indexing...';\n api('POST', '/api/stores/' + encodeURIComponent(store.id) + '/index').then(function() {\n showToast('Re-indexing complete', 'success');\n loadStoreDetail(store.id);\n }).catch(function(err) {\n showToast('Re-index failed: ' + err.message, 'error');\n btn.disabled = false;\n btn.innerHTML = ICONS.refresh + ' Re-index';\n });\n };\n\n document.getElementById('btn-delete').onclick = function() {\n showModal(\n 'Delete Store',\n 'Are you sure you want to delete \"' + store.name + '\"? This action cannot be undone.',\n function() {\n api('DELETE', '/api/stores/' + encodeURIComponent(store.id)).then(function() {\n showToast('Store deleted', 'success');\n navigate('#/stores');\n }).catch(function(err) {\n showToast('Delete failed: ' + err.message, 'error');\n });\n },\n 'Delete',\n 'btn-danger'\n );\n };\n\n var searchInput = document.getElementById('detail-search-input');\n var searchBtn = document.getElementById('detail-search-btn');\n\n function doDetailSearch() {\n var q = searchInput.value.trim();\n if (!q) return;\n var resultsDiv = document.getElementById('detail-search-results');\n resultsDiv.innerHTML = '<div class=\"loading-center\"><div class=\"spinner\"></div> Searching...</div>';\n api('POST', '/api/search', { query: q, stores: [store.id], detail: 'contextual' }).then(function(data) {\n resultsDiv.innerHTML = renderSearchResults(data);\n }).catch(function(err) {\n resultsDiv.innerHTML = '<div class=\"form-error\">' + esc(err.message) + '</div>';\n });\n }\n\n searchBtn.onclick = doDetailSearch;\n searchInput.onkeydown = function(e) {\n if (e.key === 'Enter') doDetailSearch();\n };\n }\n\n function loadDocuments(storeId, offset) {\n var limit = 15;\n var container = document.getElementById('documents-container');\n if (!container) return;\n\n api('GET', '/api/stores/' + encodeURIComponent(storeId) + '/documents?limit=' + limit + '&offset=' + offset).then(function(data) {\n if (data.total === 0) {\n container.innerHTML = '<div class=\"empty-state\" style=\"padding:var(--space-xl) 0\"><p>No indexed chunks yet. Try re-indexing this store.</p></div>';\n return;\n }\n\n var html = '<div class=\"documents-header\">' +\n '<span class=\"text-secondary\" style=\"font-size:var(--font-size-sm)\">' + data.total + ' chunks indexed</span>' +\n '<span class=\"text-tertiary\" style=\"font-size:var(--font-size-xs)\">Page ' + (Math.floor(offset / limit) + 1) + ' of ' + Math.ceil(data.total / limit) + '</span>' +\n '</div>';\n html += '<div class=\"documents-list\">';\n for (var i = 0; i < data.documents.length; i++) {\n var doc = data.documents[i];\n var path = (doc.metadata && doc.metadata.path) ? doc.metadata.path : 'unknown';\n var chunkLabel = '';\n if (doc.metadata && doc.metadata.chunkIndex != null) {\n chunkLabel = '<span class=\"document-chunk-label\">chunk ' + doc.metadata.chunkIndex + ' of ' + (doc.metadata.totalChunks || '?') + '</span>';\n }\n var typeBadge = doc.metadata && doc.metadata.type\n ? '<span class=\"badge badge-' + (doc.metadata.type === 'web' ? 'web' : doc.metadata.type === 'chunk' ? 'file' : 'file') + '\" style=\"font-size:10px;padding:1px 6px;margin-left:auto\">' + esc(doc.metadata.type) + '</span>'\n : '';\n var preview = doc.content.length > 800 ? doc.content.substring(0, 800) + ' ... (truncated)' : doc.content;\n\n html += '<div class=\"document-item\">' +\n '<div class=\"document-meta\">' +\n '<span class=\"document-index\">' + (offset + i + 1) + '</span>' +\n '<span class=\"document-path mono\">' + esc(path) + '</span>' +\n chunkLabel +\n typeBadge +\n '</div>' +\n '<pre class=\"document-content code-block\">' + esc(preview) + '</pre>' +\n '</div>';\n }\n html += '</div>';\n\n // Pagination\n html += '<div class=\"documents-pagination\">';\n if (offset > 0) {\n html += '<button class=\"btn btn-secondary btn-sm\" id=\"docs-prev\">← Previous</button>';\n }\n html += '<span class=\"text-secondary\" style=\"font-size:var(--font-size-sm)\">' +\n (offset + 1) + '–' + Math.min(offset + limit, data.total) + ' of ' + data.total +\n '</span>';\n if (offset + limit < data.total) {\n html += '<button class=\"btn btn-secondary btn-sm\" id=\"docs-next\">Next →</button>';\n }\n html += '</div>';\n\n container.innerHTML = html;\n\n // Bind pagination\n var prevBtn = document.getElementById('docs-prev');\n if (prevBtn) prevBtn.onclick = function() { loadDocuments(storeId, Math.max(0, offset - limit)); };\n var nextBtn = document.getElementById('docs-next');\n if (nextBtn) nextBtn.onclick = function() { loadDocuments(storeId, offset + limit); };\n }).catch(function(err) {\n container.innerHTML = '<div class=\"form-error\">' + esc(err.message) + '</div>';\n });\n }\n\n // ─── Create Store ───\n\n function renderCreateStore() {\n var main = document.getElementById('main-content');\n\n var html =\n '<div class=\"breadcrumb\">' +\n '<a href=\"#/stores\">Stores</a>' +\n '<span class=\"breadcrumb-sep\">' + ICONS.chevron + '</span>' +\n '<span class=\"breadcrumb-current\">Create Store</span>' +\n '</div>' +\n '<h1 class=\"page-title\" style=\"margin-bottom:var(--space-xl)\">Create Store</h1>' +\n '<div class=\"form-card\">' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Type</label>' +\n '<select class=\"form-select\" id=\"create-type\">' +\n '<option value=\"repo\">Repository</option>' +\n '<option value=\"file\">File / Directory</option>' +\n '<option value=\"web\">Web</option>' +\n '</select>' +\n '</div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Name</label>' +\n '<input class=\"form-input\" id=\"create-name\" type=\"text\" placeholder=\"my-project\" />' +\n '</div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Description <span style=\"color:var(--text-tertiary)\">(optional)</span></label>' +\n '<textarea class=\"form-textarea\" id=\"create-description\" placeholder=\"What this store contains...\"></textarea>' +\n '</div>' +\n '<div id=\"create-dynamic-fields\"></div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Tags <span style=\"color:var(--text-tertiary)\">(optional, comma-separated)</span></label>' +\n '<input class=\"form-input\" id=\"create-tags\" type=\"text\" placeholder=\"typescript, api, docs\" />' +\n '</div>' +\n '<div id=\"create-error\"></div>' +\n '<div class=\"btn-group\" style=\"margin-top:var(--space-xl)\">' +\n '<button class=\"btn btn-primary\" id=\"create-submit\">' + ICONS.plus + ' Create Store</button>' +\n '<a class=\"btn btn-secondary\" href=\"#/stores\">Cancel</a>' +\n '</div>' +\n '</div>';\n\n main.innerHTML = html;\n\n var typeSelect = document.getElementById('create-type');\n renderDynamicFields(typeSelect.value);\n typeSelect.onchange = function() { renderDynamicFields(this.value); };\n\n document.getElementById('create-submit').onclick = submitCreateStore;\n }\n\n function renderDynamicFields(type) {\n var container = document.getElementById('create-dynamic-fields');\n var html = '';\n\n switch (type) {\n case 'repo':\n html =\n '<div class=\"form-row\">' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">URL <span style=\"color:var(--text-tertiary)\">(or path)</span></label>' +\n '<input class=\"form-input\" id=\"create-url\" type=\"text\" placeholder=\"https://github.com/org/repo\" />' +\n '</div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Path <span style=\"color:var(--text-tertiary)\">(or URL)</span></label>' +\n '<input class=\"form-input\" id=\"create-path\" type=\"text\" placeholder=\"/path/to/repo\" />' +\n '</div>' +\n '</div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Branch <span style=\"color:var(--text-tertiary)\">(optional)</span></label>' +\n '<input class=\"form-input\" id=\"create-branch\" type=\"text\" placeholder=\"main\" />' +\n '</div>';\n break;\n case 'file':\n html =\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Path</label>' +\n '<input class=\"form-input\" id=\"create-path\" type=\"text\" placeholder=\"/path/to/directory\" />' +\n '<p class=\"form-hint\">Absolute path to the file or directory to index</p>' +\n '</div>';\n break;\n case 'web':\n html =\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">URL</label>' +\n '<input class=\"form-input\" id=\"create-url\" type=\"text\" placeholder=\"https://docs.example.com\" />' +\n '</div>' +\n '<div class=\"form-row\">' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Depth <span style=\"color:var(--text-tertiary)\">(optional)</span></label>' +\n '<input class=\"form-input\" id=\"create-depth\" type=\"number\" min=\"1\" placeholder=\"3\" />' +\n '<p class=\"form-hint\">How many levels deep to crawl</p>' +\n '</div>' +\n '<div class=\"form-group\">' +\n '<label class=\"form-label\">Max Pages <span style=\"color:var(--text-tertiary)\">(optional)</span></label>' +\n '<input class=\"form-input\" id=\"create-maxpages\" type=\"number\" min=\"1\" placeholder=\"50\" />' +\n '</div>' +\n '</div>';\n break;\n }\n\n container.innerHTML = html;\n }\n\n function submitCreateStore() {\n var btn = document.getElementById('create-submit');\n var errorDiv = document.getElementById('create-error');\n errorDiv.innerHTML = '';\n\n var type = document.getElementById('create-type').value;\n var name = document.getElementById('create-name').value.trim();\n\n if (!name) {\n errorDiv.innerHTML = '<div class=\"form-error\">Name is required</div>';\n return;\n }\n\n var body = { name: name, type: type };\n\n var descEl = document.getElementById('create-description');\n if (descEl && descEl.value.trim()) body.description = descEl.value.trim();\n\n var tagsEl = document.getElementById('create-tags');\n if (tagsEl && tagsEl.value.trim()) {\n body.tags = tagsEl.value.split(',').map(function(t) { return t.trim(); }).filter(function(t) { return t.length > 0; });\n }\n\n var pathEl = document.getElementById('create-path');\n if (pathEl && pathEl.value.trim()) body.path = pathEl.value.trim();\n\n var urlEl = document.getElementById('create-url');\n if (urlEl && urlEl.value.trim()) body.url = urlEl.value.trim();\n\n var branchEl = document.getElementById('create-branch');\n if (branchEl && branchEl.value.trim()) body.branch = branchEl.value.trim();\n\n var depthEl = document.getElementById('create-depth');\n if (depthEl && depthEl.value) body.depth = parseInt(depthEl.value, 10);\n\n btn.disabled = true;\n btn.innerHTML = '<div class=\"spinner\"></div> Creating...';\n\n api('POST', '/api/stores', body).then(function(store) {\n showToast('Store \"' + store.name + '\" created', 'success');\n navigate('#/stores/' + encodeURIComponent(store.id));\n }).catch(function(err) {\n errorDiv.innerHTML = '<div class=\"form-error\">' + esc(err.message) + '</div>';\n btn.disabled = false;\n btn.innerHTML = ICONS.plus + ' Create Store';\n });\n }\n\n // ─── Search View ───\n\n function renderSearchView(initialQuery) {\n var main = document.getElementById('main-content');\n\n // First load stores for the filter\n api('GET', '/api/stores').then(function(stores) {\n state.stores = stores;\n renderSearchViewContent(stores, initialQuery);\n }).catch(function() {\n renderSearchViewContent([], initialQuery);\n });\n }\n\n function renderSearchViewContent(stores, initialQuery) {\n var main = document.getElementById('main-content');\n var selectedStores = [];\n\n var storeOptions = '';\n for (var i = 0; i < stores.length; i++) {\n storeOptions +=\n '<label class=\"multi-select-option\">' +\n '<input type=\"checkbox\" value=\"' + esc(stores[i].id) + '\" />' +\n '<span class=\"badge badge-' + stores[i].type + '\" style=\"font-size:10px;padding:1px 6px\">' + stores[i].type + '</span>' +\n esc(stores[i].name) +\n '</label>';\n }\n\n var html =\n '<h1 class=\"page-title\" style=\"margin-bottom:var(--space-xl)\">Search</h1>' +\n '<div class=\"search-bar\">' +\n '<input class=\"form-input\" id=\"search-input\" type=\"text\" placeholder=\"Search across all knowledge stores...\" value=\"' + esc(initialQuery || '') + '\" />' +\n '<button class=\"btn btn-primary\" id=\"search-btn\">' + ICONS.search + ' Search</button>' +\n '</div>' +\n '<div class=\"search-options\">' +\n '<div class=\"search-option\">' +\n '<label class=\"form-label\">Detail Level</label>' +\n '<select class=\"form-select\" id=\"search-detail\">' +\n '<option value=\"minimal\">Minimal</option>' +\n '<option value=\"contextual\" selected>Contextual</option>' +\n '<option value=\"full\">Full</option>' +\n '</select>' +\n '</div>' +\n '<div class=\"search-option\">' +\n '<label class=\"form-label\">Stores</label>' +\n '<div class=\"multi-select\" id=\"store-filter\">' +\n '<div class=\"multi-select-trigger\" id=\"store-filter-trigger\">All stores</div>' +\n '<div class=\"multi-select-dropdown\" id=\"store-filter-dropdown\">' +\n storeOptions +\n '</div>' +\n '</div>' +\n '</div>' +\n '</div>' +\n '<div id=\"search-results\"></div>';\n\n main.innerHTML = html;\n\n // Multi-select behavior\n var trigger = document.getElementById('store-filter-trigger');\n var dropdown = document.getElementById('store-filter-dropdown');\n\n trigger.onclick = function(e) {\n e.stopPropagation();\n dropdown.classList.toggle('open');\n };\n\n document.addEventListener('click', function closeDropdown(e) {\n if (!dropdown.contains(e.target) && e.target !== trigger) {\n dropdown.classList.remove('open');\n }\n });\n\n var checkboxes = dropdown.querySelectorAll('input[type=\"checkbox\"]');\n for (var c = 0; c < checkboxes.length; c++) {\n checkboxes[c].onchange = function() {\n selectedStores = [];\n for (var k = 0; k < checkboxes.length; k++) {\n if (checkboxes[k].checked) selectedStores.push(checkboxes[k].value);\n }\n trigger.textContent = selectedStores.length === 0 ? 'All stores' : selectedStores.length + ' store' + (selectedStores.length > 1 ? 's' : '') + ' selected';\n };\n }\n\n function doSearch() {\n var q = document.getElementById('search-input').value.trim();\n if (!q) return;\n\n var detail = document.getElementById('search-detail').value;\n var resultsDiv = document.getElementById('search-results');\n resultsDiv.innerHTML = '<div class=\"loading-center\"><div class=\"spinner\"></div> Searching...</div>';\n\n // Update URL\n var newHash = '#/search?q=' + encodeURIComponent(q);\n if (window.location.hash !== newHash) {\n history.replaceState(null, '', newHash);\n }\n\n var searchBody = { query: q, detail: detail };\n if (selectedStores.length > 0) searchBody.stores = selectedStores;\n\n api('POST', '/api/search', searchBody).then(function(data) {\n resultsDiv.innerHTML = renderSearchResults(data);\n }).catch(function(err) {\n resultsDiv.innerHTML = '<div class=\"form-error\">' + esc(err.message) + '</div>';\n });\n }\n\n document.getElementById('search-btn').onclick = doSearch;\n document.getElementById('search-input').onkeydown = function(e) {\n if (e.key === 'Enter') doSearch();\n };\n\n // Auto-search if we have a query\n if (initialQuery) {\n doSearch();\n }\n\n // Focus input\n document.getElementById('search-input').focus();\n }\n\n // ─── Search Results Renderer ───\n\n function renderSearchResults(data) {\n var results = data.results || [];\n var html = '';\n\n // Meta bar\n var metaParts = [];\n metaParts.push('<strong>' + results.length + '</strong> result' + (results.length !== 1 ? 's' : ''));\n if (data.timeMs != null) metaParts.push(data.timeMs + 'ms');\n if (data.mode) metaParts.push(esc(data.mode) + ' mode');\n\n var confidenceHtml = '';\n if (data.confidence) {\n var confClass = data.confidence === 'high' ? 'confidence-high' : data.confidence === 'medium' ? 'confidence-medium' : 'confidence-low';\n confidenceHtml = '<span class=\"meta-separator\"></span><span class=\"confidence-badge ' + confClass + '\">' + esc(data.confidence) + ' confidence</span>';\n }\n\n html += '<div class=\"search-meta-bar\">';\n html += metaParts.join('<span class=\"meta-separator\"></span>');\n html += confidenceHtml;\n html += '</div>';\n\n if (results.length === 0) {\n html += '<div class=\"empty-state\"><div class=\"empty-state-title\">No results found</div><p>Try broadening your search query or checking different stores.</p></div>';\n return html;\n }\n\n html += '<div class=\"results-list\">';\n for (var i = 0; i < results.length; i++) {\n html += renderResultCard(results[i], i);\n }\n html += '</div>';\n\n return html;\n }\n\n function renderResultCard(result, index) {\n var summary = result.summary || {};\n var context = result.context;\n var full = result.full;\n var pct = Math.round((result.score || 0) * 100);\n var sc = scoreColor(result.score || 0);\n var scCls = scoreClass(result.score || 0);\n\n var hasContext = context && (\n (context.interfaces && context.interfaces.length > 0) ||\n (context.keyImports && context.keyImports.length > 0) ||\n (context.relatedConcepts && context.relatedConcepts.length > 0) ||\n context.usage\n );\n\n var hasFull = full && (\n (full.completeCode && full.completeCode.length > 0) ||\n (full.documentation && full.documentation.length > 0)\n );\n\n var locParts = (summary.location || '').split(':');\n var fileName = locParts[0] || '';\n var lineNum = locParts[1] || '';\n\n var html =\n '<div class=\"result-card\">' +\n '<div class=\"result-header\">' +\n '<div class=\"result-rank\">' + (index + 1) + '</div>' +\n '<div class=\"result-main\">' +\n '<div class=\"result-title-row\">' +\n (summary.type ? resultTypeIcon(summary.type) : '') +\n '<span class=\"result-name\">' + esc(summary.name || 'Unknown') + '</span>' +\n '<div class=\"score-bar-container\">' +\n '<div class=\"score-bar-track\"><div class=\"score-bar-fill\" style=\"width:' + pct + '%;background:' + sc + '\"></div></div>' +\n '<span class=\"score-label score-' + scCls + '\">' + pct + '%</span>' +\n '</div>' +\n '</div>';\n\n if (summary.signature) {\n html += '<div class=\"result-signature\">' + esc(summary.signature) + '</div>';\n }\n if (summary.purpose) {\n html += '<p class=\"result-purpose\">' + esc(summary.purpose) + '</p>';\n }\n\n html += '<div class=\"result-meta meta-row\">';\n if (fileName) {\n html += '<span class=\"result-location mono\" title=\"' + esc(summary.location || '') + '\">' + esc(fileName) + (lineNum ? '<span class=\"line-number\">:' + esc(lineNum) + '</span>' : '') + '</span>';\n }\n if (summary.storeName) {\n html += '<span class=\"meta-separator\"></span><span class=\"result-store\">' + esc(summary.storeName) + '</span>';\n }\n html += '</div>';\n\n if (summary.relevanceReason) {\n html += '<div class=\"result-relevance\">' + esc(summary.relevanceReason) + '</div>';\n }\n\n html += '</div></div>'; // close result-main, result-header\n\n // Expandable details\n if (hasContext || hasFull) {\n var detailLabel = (hasContext && hasFull) ? 'Context & Source Code' : hasContext ? 'Context' : 'Source Code';\n html += '<details><summary>' + detailLabel + '</summary><div class=\"details-content\">';\n\n if (hasContext) {\n html += renderContextSection(context);\n }\n if (hasFull) {\n html += renderFullSection(full);\n }\n\n html += '</div></details>';\n }\n\n html += '</div>'; // close result-card\n return html;\n }\n\n function renderContextSection(ctx) {\n var html = '';\n\n if (ctx.interfaces && ctx.interfaces.length > 0) {\n html += '<div class=\"context-group\"><div class=\"section-label\">Interfaces</div><ul class=\"pill-list\">';\n for (var i = 0; i < ctx.interfaces.length; i++) html += '<li class=\"pill\">' + esc(ctx.interfaces[i]) + '</li>';\n html += '</ul></div>';\n }\n\n if (ctx.keyImports && ctx.keyImports.length > 0) {\n html += '<div class=\"context-group\"><div class=\"section-label\">Key Imports</div><ul class=\"pill-list\">';\n for (var j = 0; j < ctx.keyImports.length; j++) html += '<li class=\"pill\">' + esc(ctx.keyImports[j]) + '</li>';\n html += '</ul></div>';\n }\n\n if (ctx.relatedConcepts && ctx.relatedConcepts.length > 0) {\n html += '<div class=\"context-group\"><div class=\"section-label\">Related Concepts</div><ul class=\"pill-list\">';\n for (var k = 0; k < ctx.relatedConcepts.length; k++) html += '<li class=\"pill\">' + esc(ctx.relatedConcepts[k]) + '</li>';\n html += '</ul></div>';\n }\n\n if (ctx.usage) {\n html +=\n '<div class=\"context-group\"><div class=\"section-label\">Usage</div>' +\n '<div class=\"usage-stats\">' +\n '<span class=\"usage-stat\"><span class=\"usage-value\">' + ctx.usage.calledBy + '</span><span class=\"usage-label\">called by</span></span>' +\n '<span class=\"usage-stat\"><span class=\"usage-value\">' + ctx.usage.calls + '</span><span class=\"usage-label\">calls</span></span>' +\n '</div></div>';\n }\n\n return html;\n }\n\n function renderFullSection(full) {\n var html = '';\n\n if (full.documentation && full.documentation.length > 0) {\n html += '<div class=\"full-group\"><div class=\"section-label\">Documentation</div><div class=\"documentation-text\">' + esc(full.documentation) + '</div></div>';\n }\n\n if (full.completeCode && full.completeCode.length > 0) {\n html += '<div class=\"full-group\"><div class=\"section-label\">Source Code</div><pre class=\"code-block\"><code>' + esc(full.completeCode) + '</code></pre></div>';\n }\n\n return html;\n }\n\n // ─── Bootstrap ───\n\n window.addEventListener('hashchange', renderApp);\n renderApp();\n\n })();\n </script>\n</body>\n</html>`;\n}\n","import { spawnSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { DEFAULT_REPOS, type DefaultRepo } from '../../defaults/repos.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport type { GlobalOptions } from '../program.js';\n\nconst DEFAULT_REPOS_DIR = join(homedir(), '.bluera', 'bluera-knowledge', 'repos');\n\nexport function createSetupCommand(getOptions: () => GlobalOptions): Command {\n const setup = new Command('setup').description(\n 'Quick-start with pre-configured Claude/Anthropic documentation repos'\n );\n\n setup\n .command('repos')\n .description(\n 'Clone repos to ~/.bluera/bluera-knowledge/repos/, create stores, index all content'\n )\n .option(\n '--repos-dir <path>',\n 'Clone destination (default: ~/.bluera/bluera-knowledge/repos/)',\n DEFAULT_REPOS_DIR\n )\n .option('--skip-clone', \"Don't clone; assume repos already exist locally\")\n .option('--skip-index', \"Clone and create stores but don't index yet\")\n .option('--only <names>', 'Only process matching repos (comma-separated, partial match)')\n .option('--list', 'Print available repos without cloning/indexing')\n .action(\n async (options: {\n reposDir: string;\n skipClone?: boolean;\n skipIndex?: boolean;\n only?: string;\n list?: boolean;\n }) => {\n const globalOpts = getOptions();\n\n // List mode: just show available repos\n if (options.list === true) {\n console.log('\\nDefault repositories:\\n');\n for (const repo of DEFAULT_REPOS) {\n console.log(` ${repo.name}`);\n console.log(` URL: ${repo.url}`);\n console.log(` Description: ${repo.description}`);\n console.log(` Tags: ${repo.tags.join(', ')}`);\n console.log('');\n }\n return;\n }\n\n // Filter repos BEFORE creating services to avoid cleanup bypass\n let repos: readonly DefaultRepo[] = DEFAULT_REPOS;\n if (options.only !== undefined && options.only !== '') {\n const onlyNames = options.only.split(',').map((n) => n.trim().toLowerCase());\n repos = DEFAULT_REPOS.filter((r) =>\n onlyNames.some((n) => r.name.toLowerCase().includes(n))\n );\n if (repos.length === 0) {\n console.error(`No repos matched: ${options.only}`);\n console.log('Available repos:', DEFAULT_REPOS.map((r) => r.name).join(', '));\n process.exitCode = 1;\n return;\n }\n }\n\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n try {\n console.log(`\\nSetting up ${String(repos.length)} repositories...\\n`);\n\n // Ensure repos directory exists\n await mkdir(options.reposDir, { recursive: true });\n\n for (const repo of repos) {\n const repoPath = join(options.reposDir, repo.name);\n const spinner = ora(`Processing ${repo.name}`).start();\n\n try {\n // Step 1: Clone if needed\n if (options.skipClone !== true) {\n if (existsSync(repoPath)) {\n spinner.text = `${repo.name}: Already cloned, pulling latest...`;\n const pullResult = spawnSync('git', ['pull', '--ff-only'], {\n cwd: repoPath,\n stdio: 'pipe',\n });\n if (pullResult.status !== 0) {\n // Pull failed (maybe diverged), that's okay\n spinner.text = `${repo.name}: Pull skipped (local changes)`;\n }\n } else {\n spinner.text = `${repo.name}: Cloning...`;\n const cloneResult = spawnSync('git', ['clone', repo.url, repoPath], {\n stdio: 'pipe',\n });\n if (cloneResult.status !== 0) {\n const errorMessage =\n cloneResult.stderr.length > 0\n ? cloneResult.stderr.toString()\n : 'Git clone failed';\n throw new Error(errorMessage);\n }\n }\n }\n\n // Step 2: Create store if needed\n spinner.text = `${repo.name}: Creating store...`;\n const existingStore = await services.store.getByIdOrName(repo.name);\n\n let storeId: string;\n if (existingStore) {\n storeId = existingStore.id;\n spinner.text = `${repo.name}: Store already exists`;\n } else {\n const result = await services.store.create({\n name: repo.name,\n type: 'repo',\n path: repoPath,\n description: repo.description,\n tags: repo.tags,\n });\n\n if (!result.success) {\n throw new Error(\n result.error instanceof Error ? result.error.message : String(result.error)\n );\n }\n storeId = result.data.id;\n }\n\n // Step 3: Index if needed\n if (options.skipIndex !== true) {\n spinner.text = `${repo.name}: Indexing...`;\n const store = await services.store.getByIdOrName(storeId);\n if (store) {\n services.lance.setDimensions(await services.embeddings.ensureDimensions());\n await services.lance.initialize(store.id);\n const indexResult = await services.index.indexStore(store, (event) => {\n if (event.type === 'progress') {\n spinner.text = `${repo.name}: Indexing ${String(event.current)}/${String(event.total)} files`;\n }\n });\n\n if (indexResult.success) {\n spinner.succeed(\n `${repo.name}: ${String(indexResult.data.filesIndexed)} docs, ${String(indexResult.data.chunksCreated)} chunks`\n );\n } else {\n throw new Error(\n indexResult.error instanceof Error\n ? indexResult.error.message\n : String(indexResult.error)\n );\n }\n }\n } else {\n spinner.succeed(`${repo.name}: Ready (indexing skipped)`);\n }\n } catch (error) {\n spinner.fail(\n `${repo.name}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n console.log('\\nSetup complete! Use \"bluera-knowledge search <query>\" to search.\\n');\n } finally {\n await destroyServices(services);\n }\n }\n );\n\n return setup;\n}\n","/**\n * Default repositories for quick setup.\n * These are Anthropic/Claude-related repositories that provide\n * useful knowledge for Claude Code development.\n */\n\nexport interface DefaultRepo {\n /** Git URL for cloning */\n url: string;\n /** Friendly name for the store */\n name: string;\n /** Description of what this repo contains */\n description: string;\n /** Tags for categorization */\n tags: string[];\n}\n\nexport const DEFAULT_REPOS: readonly DefaultRepo[] = [\n {\n url: 'git@github.com:ericbuess/claude-code-docs.git',\n name: 'claude-code-docs',\n description: 'Claude Code documentation',\n tags: ['claude', 'docs', 'claude-code'],\n },\n {\n url: 'git@github.com:anthropics/claude-code.git',\n name: 'claude-code',\n description: 'Claude Code CLI tool source',\n tags: ['claude', 'cli', 'anthropic'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-python.git',\n name: 'claude-agent-sdk-python',\n description: 'Claude Agent SDK for Python',\n tags: ['claude', 'sdk', 'python', 'agents'],\n },\n {\n url: 'git@github.com:anthropics/skills.git',\n name: 'claude-skills',\n description: 'Claude skills and capabilities',\n tags: ['claude', 'skills'],\n },\n {\n url: 'git@github.com:anthropics/claude-quickstarts.git',\n name: 'claude-quickstarts',\n description: 'Claude quickstart examples and tutorials',\n tags: ['claude', 'examples', 'tutorials'],\n },\n {\n url: 'git@github.com:anthropics/claude-plugins-official.git',\n name: 'claude-plugins',\n description: 'Official Claude plugins',\n tags: ['claude', 'plugins'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-typescript.git',\n name: 'claude-agent-sdk-typescript',\n description: 'Claude Agent SDK for TypeScript',\n tags: ['claude', 'sdk', 'typescript', 'agents'],\n },\n {\n url: 'git@github.com:anthropics/claude-agent-sdk-demos.git',\n name: 'claude-agent-sdk-demos',\n description: 'Claude Agent SDK demo applications',\n tags: ['claude', 'sdk', 'demos', 'examples'],\n },\n];\n","import { rm, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport { isGitUrl } from '../../plugin/git-clone.js';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { checkStoreModelCompatibility } from '../../utils/model-validation.js';\nimport type { Store, StoreType } from '../../types/store.js';\nimport type { GlobalOptions } from '../program.js';\n\n/** Health check severity level */\ntype HealthSeverity = 'error' | 'warning';\n\n/** Health check issue code */\ntype HealthIssueCode = 'PATH_NOT_FOUND' | 'SCHEMA_V1' | 'MODEL_MISMATCH';\n\n/** A single health check issue */\ninterface HealthIssue {\n severity: HealthSeverity;\n code: HealthIssueCode;\n message: string;\n resolution: string;\n}\n\n/** Health check result for a single store */\ninterface HealthResult {\n storeId: string;\n storeName: string;\n storeType: StoreType;\n status: 'healthy' | 'warning' | 'error';\n issues: HealthIssue[];\n}\n\n/**\n * Check if a path exists\n */\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check health of a single store\n */\nasync function checkStoreHealth(store: Store, currentModelId: string): Promise<HealthResult> {\n const issues: HealthIssue[] = [];\n\n // 1. Path check - file/repo only\n if (store.type === 'file' || store.type === 'repo') {\n const exists = await pathExists(store.path);\n if (!exists) {\n issues.push({\n severity: 'error',\n code: 'PATH_NOT_FOUND',\n message: `Path does not exist: ${store.path}`,\n resolution: 'Re-create store or fix projectRoot if path was relative',\n });\n }\n }\n\n // 2. Model compatibility check (reuses existing validation)\n const modelCheck = checkStoreModelCompatibility(store, { currentModelId });\n if (!modelCheck.compatible) {\n const isSchemaV1 = modelCheck.reason?.includes('v1') === true;\n issues.push({\n severity: 'warning',\n code: isSchemaV1 ? 'SCHEMA_V1' : 'MODEL_MISMATCH',\n message: modelCheck.reason ?? 'Model incompatibility',\n resolution: `Run: bluera-knowledge index ${store.name}`,\n });\n }\n\n // Determine overall status\n const hasError = issues.some((i) => i.severity === 'error');\n const hasWarning = issues.some((i) => i.severity === 'warning');\n const status = hasError ? 'error' : hasWarning ? 'warning' : 'healthy';\n\n return {\n storeId: store.id,\n storeName: store.name,\n storeType: store.type,\n status,\n issues,\n };\n}\n\nexport function createStoreCommand(getOptions: () => GlobalOptions): Command {\n const store = new Command('store').description(\n 'Manage knowledge stores (collections of indexed documents)'\n );\n\n store\n .command('list')\n .description('Show all stores with their type (file/repo/web) and ID')\n .option('-t, --type <type>', 'Filter by type: file, repo, or web')\n .action(async (options: { type?: StoreType }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n try {\n const stores = await services.store.list(options.type);\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(stores, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: just list store names, one per line\n for (const s of stores) {\n console.log(s.name);\n }\n } else {\n if (stores.length === 0) {\n console.log('No stores found.');\n } else {\n console.log('\\nStores:\\n');\n for (const s of stores) {\n console.log(` ${s.name} (${s.type}) - ${s.id}`);\n }\n console.log('');\n }\n }\n } finally {\n await destroyServices(services);\n }\n });\n\n store\n .command('create <name>')\n .description('Create a new store pointing to a local path or URL')\n .requiredOption(\n '-t, --type <type>',\n 'Store type: file (local dir), repo (git), web (crawled site)'\n )\n .requiredOption('-s, --source <path>', 'Local path for file/repo stores, URL for web stores')\n .option('-b, --branch <branch>', 'Git branch to clone (repo stores only)')\n .option('-d, --description <desc>', 'Optional description for the store')\n .option('--tags <tags>', 'Comma-separated tags for filtering')\n .action(\n async (\n name: string,\n options: {\n type: StoreType;\n source: string;\n branch?: string;\n description?: string;\n tags?: string;\n }\n ) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n // Detect if source is a URL (for repo stores that should clone from remote)\n // Supports http://, https://, and git@ SSH URLs\n const isUrl = isGitUrl(options.source);\n const result = await services.store.create({\n name,\n type: options.type,\n path:\n options.type === 'file' || (options.type === 'repo' && !isUrl)\n ? options.source\n : undefined,\n url:\n options.type === 'web' || (options.type === 'repo' && isUrl)\n ? options.source\n : undefined,\n branch: options.type === 'repo' ? options.branch : undefined,\n description: options.description,\n tags: options.tags?.split(',').map((t) => t.trim()),\n });\n\n if (result.success) {\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result.data, null, 2));\n } else {\n console.log(`\\nCreated store: ${result.data.name} (${result.data.id})\\n`);\n }\n } else {\n console.error(`Error: ${result.error.message}`);\n exitCode = 1;\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n }\n );\n\n store\n .command('info <store>')\n .description('Show store details: ID, type, path/URL, timestamps')\n .action(async (storeIdOrName: string) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n storeInfo: try {\n const s = await services.store.getByIdOrName(storeIdOrName);\n\n if (s === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n break storeInfo;\n }\n\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(s, null, 2));\n } else {\n console.log(`\\nStore: ${s.name}`);\n console.log(` ID: ${s.id}`);\n console.log(` Type: ${s.type}`);\n if ('path' in s) console.log(` Path: ${s.path}`);\n if ('url' in s && s.url !== undefined) console.log(` URL: ${s.url}`);\n if (s.description !== undefined) console.log(` Description: ${s.description}`);\n console.log(` Created: ${s.createdAt.toISOString()}`);\n console.log(` Updated: ${s.updatedAt.toISOString()}`);\n console.log('');\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n store\n .command('delete <store>')\n .description('Remove store and its indexed documents from LanceDB')\n .option('-f, --force', 'Delete without confirmation prompt')\n .option('-y, --yes', 'Alias for --force')\n .action(async (storeIdOrName: string, options: { force?: boolean; yes?: boolean }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n storeDelete: try {\n const s = await services.store.getByIdOrName(storeIdOrName);\n\n if (s === undefined) {\n console.error(`Error: Store not found: ${storeIdOrName}`);\n exitCode = 3;\n break storeDelete;\n }\n\n // Require --force or -y in non-TTY mode, prompt in TTY mode\n const skipConfirmation = options.force === true || options.yes === true;\n if (!skipConfirmation) {\n if (!process.stdin.isTTY) {\n console.error(\n 'Error: Use --force or -y to delete without confirmation in non-interactive mode'\n );\n exitCode = 1;\n break storeDelete;\n }\n // Interactive confirmation\n const readline = await import('node:readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n const answer = await new Promise<string>((resolve) => {\n rl.question(`Delete store \"${s.name}\"? [y/N] `, resolve);\n });\n rl.close();\n if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {\n console.log('Cancelled.');\n // exitCode stays 0 for user-initiated cancellation\n break storeDelete;\n }\n }\n\n // Delete LanceDB table first (so searches don't return results for deleted store)\n await services.lance.deleteStore(s.id);\n\n // Delete code graph file\n await services.codeGraph.deleteGraph(s.id);\n\n // Delete manifest file (matches MCP/server behavior)\n await services.manifest.delete(s.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n if (s.type === 'repo' && 'url' in s && s.url !== undefined) {\n const dataDir = services.config.resolveDataDir();\n const repoPath = join(dataDir, 'repos', s.id);\n await rm(repoPath, { recursive: true, force: true });\n }\n\n // Delete from registry last\n const result = await services.store.delete(s.id);\n\n if (result.success) {\n console.log(`Deleted store: ${s.name}`);\n } else {\n console.error(`Error: ${result.error.message}`);\n exitCode = 1;\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n // Set exit code and let Node.js exit naturally after event loop drains\n // Using process.exit() causes mutex crashes from native code (LanceDB, tree-sitter)\n process.exitCode = exitCode;\n }\n });\n\n store\n .command('health')\n .description('Check health of all stores: path existence, model compatibility')\n .option('-s, --store <name>', 'Check a specific store only')\n .action(async (options: { store?: string }) => {\n const globalOpts = getOptions();\n const services = await createServices(\n globalOpts.config,\n globalOpts.dataDir,\n globalOpts.projectRoot\n );\n let exitCode = 0;\n try {\n const currentModelId = services.store.getCurrentModelId();\n let storesToCheck: Store[];\n\n if (options.store !== undefined) {\n const s = await services.store.getByIdOrName(options.store);\n if (s === undefined) {\n console.error(`Error: Store not found: ${options.store}`);\n exitCode = 1;\n return;\n }\n storesToCheck = [s];\n } else {\n storesToCheck = await services.store.list();\n }\n\n if (storesToCheck.length === 0) {\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify({ stores: [], exitCode: 0 }, null, 2));\n } else if (globalOpts.quiet !== true) {\n console.log('No stores found.');\n }\n return;\n }\n\n // Check health of each store\n const results: HealthResult[] = [];\n for (const s of storesToCheck) {\n const result = await checkStoreHealth(s, currentModelId);\n results.push(result);\n }\n\n // Determine exit code: 1 for any error, 2 for warning-only, 0 for healthy\n const hasError = results.some((r) => r.status === 'error');\n const hasWarning = results.some((r) => r.status === 'warning');\n exitCode = hasError ? 1 : hasWarning ? 2 : 0;\n\n // Output results\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify({ stores: results, exitCode }, null, 2));\n } else if (globalOpts.quiet === true) {\n // Quiet mode: no output, just exit code\n } else {\n // Human-readable output\n console.log('\\nStore Health Check\\n');\n for (const result of results) {\n const statusIcon =\n result.status === 'healthy' ? '✓' : result.status === 'warning' ? '⚠' : '✗';\n const statusColor =\n result.status === 'healthy'\n ? '\\x1b[32m'\n : result.status === 'warning'\n ? '\\x1b[33m'\n : '\\x1b[31m';\n const reset = '\\x1b[0m';\n\n console.log(\n ` ${statusColor}${statusIcon}${reset} ${result.storeName} (${result.storeType})`\n );\n for (const issue of result.issues) {\n const issueIcon = issue.severity === 'error' ? ' ✗' : ' ⚠';\n console.log(` ${issueIcon} ${issue.message}`);\n console.log(` Fix: ${issue.resolution}`);\n }\n }\n\n // Summary\n const healthy = results.filter((r) => r.status === 'healthy').length;\n const warnings = results.filter((r) => r.status === 'warning').length;\n const errors = results.filter((r) => r.status === 'error').length;\n console.log('');\n console.log(\n `Summary: ${String(healthy)} healthy, ${String(warnings)} warnings, ${String(errors)} errors`\n );\n console.log('');\n }\n } finally {\n await destroyServices(services);\n }\n if (exitCode !== 0) {\n process.exitCode = exitCode;\n }\n });\n\n return store;\n}\n","import { rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Command } from 'commander';\nimport { createServices, destroyServices } from '../../services/index.js';\nimport { JobService } from '../../services/job.service.js';\nimport { ProjectRootService } from '../../services/project-root.service.js';\nimport { StoreDefinitionService } from '../../services/store-definition.service.js';\nimport {\n isFileStoreDefinition,\n isRepoStoreDefinition,\n isWebStoreDefinition,\n} from '../../types/store-definition.js';\nimport { spawnBackgroundWorker } from '../../workers/spawn-worker.js';\nimport type { StoreService } from '../../services/store.service.js';\nimport type { StoreDefinition } from '../../types/store-definition.js';\nimport type { GlobalOptions } from '../program.js';\n\ninterface SyncResult {\n created: string[];\n skipped: string[];\n failed: Array<{ name: string; error: string }>;\n orphans: string[];\n pruned: string[];\n dryRun: boolean;\n wouldCreate: string[];\n wouldPrune: string[];\n reindexJobs: Array<{ store: string; jobId: string }>;\n wouldReindex: string[];\n}\n\n/**\n * Create a store from a definition\n */\nasync function createStoreFromDefinition(\n def: StoreDefinition,\n defService: StoreDefinitionService,\n storeService: StoreService\n): Promise<{ success: true } | { success: false; error: string }> {\n try {\n if (isFileStoreDefinition(def)) {\n const resolvedPath = defService.resolvePath(def.path);\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'file',\n path: resolvedPath,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n if (isRepoStoreDefinition(def)) {\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'repo',\n url: def.url,\n branch: def.branch,\n depth: def.depth,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n if (isWebStoreDefinition(def)) {\n const createResult = await storeService.create(\n {\n name: def.name,\n type: 'web',\n url: def.url,\n depth: def.depth,\n maxPages: def.maxPages,\n crawlInstructions: def.crawlInstructions,\n extractInstructions: def.extractInstructions,\n description: def.description,\n tags: def.tags,\n },\n { skipDefinitionSync: true }\n );\n if (!createResult.success) {\n return { success: false, error: createResult.error.message };\n }\n return { success: true };\n }\n\n return { success: false, error: 'Unknown store definition type' };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport function createSyncCommand(getOptions: () => GlobalOptions): Command {\n const sync = new Command('sync').description(\n 'Sync stores from definitions config (bootstrap on fresh clone)'\n );\n\n sync\n .option('--dry-run', 'Show what would happen without making changes')\n .option('--prune', 'Remove stores not in definitions')\n .option('--reindex', 'Re-index existing stores after sync')\n .action(async (options: { dryRun?: boolean; prune?: boolean; reindex?: boolean }) => {\n const globalOpts = getOptions();\n const projectRoot = globalOpts.projectRoot ?? ProjectRootService.resolve();\n\n const defService = new StoreDefinitionService(projectRoot);\n const services = await createServices(globalOpts.config, globalOpts.dataDir, projectRoot);\n\n try {\n const config = await defService.load();\n const existingStores = await services.store.list();\n const existingNames = new Set(existingStores.map((s) => s.name));\n const definedNames = new Set(config.stores.map((d) => d.name));\n\n const result: SyncResult = {\n created: [],\n skipped: [],\n failed: [],\n orphans: [],\n pruned: [],\n dryRun: options.dryRun === true,\n wouldCreate: [],\n wouldPrune: [],\n reindexJobs: [],\n wouldReindex: [],\n };\n\n // Process each definition\n for (const def of config.stores) {\n if (existingNames.has(def.name)) {\n result.skipped.push(def.name);\n continue;\n }\n\n if (options.dryRun === true) {\n result.wouldCreate.push(def.name);\n continue;\n }\n\n const createResult = await createStoreFromDefinition(def, defService, services.store);\n if (createResult.success) {\n result.created.push(def.name);\n } else {\n result.failed.push({ name: def.name, error: createResult.error });\n }\n }\n\n // Find orphans\n for (const store of existingStores) {\n if (!definedNames.has(store.name)) {\n result.orphans.push(store.name);\n }\n }\n\n // Prune orphans if requested\n if (options.prune === true && result.orphans.length > 0) {\n if (options.dryRun === true) {\n result.wouldPrune = [...result.orphans];\n } else {\n for (const orphanName of result.orphans) {\n const store = await services.store.getByName(orphanName);\n if (store !== undefined) {\n // Full cleanup like store delete command\n await services.lance.deleteStore(store.id);\n await services.codeGraph.deleteGraph(store.id);\n await services.manifest.delete(store.id);\n\n // For repo stores cloned from URL, remove the cloned directory\n if (store.type === 'repo' && 'url' in store && store.url !== undefined) {\n const dataDir = services.config.resolveDataDir();\n const repoPath = join(dataDir, 'repos', store.id);\n await rm(repoPath, { recursive: true, force: true });\n }\n\n const deleteResult = await services.store.delete(store.id, {\n skipDefinitionSync: true,\n });\n if (deleteResult.success) {\n result.pruned.push(orphanName);\n }\n }\n }\n }\n }\n\n // Re-index existing stores if requested\n if (options.reindex === true && result.skipped.length > 0) {\n if (options.dryRun === true) {\n result.wouldReindex = [...result.skipped];\n } else {\n const dataDir = globalOpts.dataDir ?? services.config.resolveDataDir();\n const jobService = new JobService(dataDir);\n\n for (const storeName of result.skipped) {\n const store = await services.store.getByName(storeName);\n if (store !== undefined) {\n const job = jobService.createJob({\n type: 'index',\n details: { storeId: store.id, storeName: store.name },\n message: `Re-indexing ${storeName}...`,\n });\n spawnBackgroundWorker(job.id, dataDir);\n result.reindexJobs.push({ store: storeName, jobId: job.id });\n }\n }\n }\n }\n\n // Output result\n if (globalOpts.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n printHumanReadable(result, globalOpts.quiet === true);\n }\n } finally {\n await destroyServices(services);\n }\n });\n\n return sync;\n}\n\nfunction printHumanReadable(result: SyncResult, quiet: boolean): void {\n if (quiet) {\n // Just print created/pruned/reindexed store names\n for (const name of result.created) {\n console.log(`created: ${name}`);\n }\n for (const name of result.pruned) {\n console.log(`pruned: ${name}`);\n }\n for (const { store, jobId } of result.reindexJobs) {\n console.log(`reindexing: ${store} (${jobId})`);\n }\n for (const name of result.wouldCreate) {\n console.log(`would create: ${name}`);\n }\n for (const name of result.wouldPrune) {\n console.log(`would prune: ${name}`);\n }\n for (const name of result.wouldReindex) {\n console.log(`would reindex: ${name}`);\n }\n return;\n }\n\n if (result.dryRun) {\n console.log('\\n[DRY RUN] No changes made.\\n');\n } else {\n console.log('\\nSync completed.\\n');\n }\n\n if (result.created.length > 0) {\n console.log(`Created (${String(result.created.length)}):`);\n for (const name of result.created) {\n console.log(` + ${name}`);\n }\n }\n\n if (result.wouldCreate.length > 0) {\n console.log(`Would create (${String(result.wouldCreate.length)}):`);\n for (const name of result.wouldCreate) {\n console.log(` + ${name}`);\n }\n }\n\n if (result.skipped.length > 0) {\n console.log(`Skipped (already exist) (${String(result.skipped.length)}):`);\n for (const name of result.skipped) {\n console.log(` - ${name}`);\n }\n }\n\n if (result.failed.length > 0) {\n console.log(`Failed (${String(result.failed.length)}):`);\n for (const { name, error } of result.failed) {\n console.log(` ! ${name}: ${error}`);\n }\n }\n\n if (result.orphans.length > 0) {\n console.log(`Orphans (not in definitions) (${String(result.orphans.length)}):`);\n for (const name of result.orphans) {\n console.log(` ? ${name}`);\n }\n }\n\n if (result.pruned.length > 0) {\n console.log(`Pruned (${String(result.pruned.length)}):`);\n for (const name of result.pruned) {\n console.log(` x ${name}`);\n }\n }\n\n if (result.wouldPrune.length > 0) {\n console.log(`Would prune (${String(result.wouldPrune.length)}):`);\n for (const name of result.wouldPrune) {\n console.log(` x ${name}`);\n }\n }\n\n if (result.reindexJobs.length > 0) {\n console.log(`Reindexing started (${String(result.reindexJobs.length)}):`);\n for (const { store, jobId } of result.reindexJobs) {\n console.log(` ↻ ${store} (Job: ${jobId})`);\n }\n }\n\n if (result.wouldReindex.length > 0) {\n console.log(`Would reindex (${String(result.wouldReindex.length)}):`);\n for (const name of result.wouldReindex) {\n console.log(` ↻ ${name}`);\n }\n }\n\n console.log('');\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\n\ninterface PackageJson {\n version: string;\n}\n\nfunction getVersion(): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const content = readFileSync(join(__dirname, '../package.json'), 'utf-8');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const pkg: PackageJson = JSON.parse(content);\n return pkg.version;\n}\n\nconst version = getVersion();\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('bluera-knowledge')\n .description('CLI tool for managing knowledge stores with semantic search')\n .version(version);\n\n program\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --data-dir <path>', 'Data directory')\n .option('-p, --project-root <path>', 'Project root directory (for resolving relative paths)')\n .option('-f, --format <format>', 'Output format: json | table | plain', 'table')\n .option('-q, --quiet', 'Suppress non-essential output');\n\n return program;\n}\n\nexport interface GlobalOptions {\n config?: string | undefined;\n dataDir?: string | undefined;\n projectRoot?: string | undefined;\n format: 'json' | 'table' | 'plain';\n quiet?: boolean | undefined;\n}\n\nexport function getGlobalOptions(program: Command): GlobalOptions {\n const opts = program.opts<GlobalOptions>();\n return {\n config: opts.config,\n dataDir: opts.dataDir,\n projectRoot: opts.projectRoot,\n format: opts.format,\n quiet: opts.quiet,\n };\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { AdapterRegistry } from './analysis/adapter-registry.js';\nimport { ZilAdapter } from './analysis/zil/index.js';\nimport { createCrawlCommand } from './cli/commands/crawl.js';\nimport { createIndexCommand } from './cli/commands/index-cmd.js';\nimport { createMCPCommand } from './cli/commands/mcp.js';\nimport {\n createAddRepoCommand,\n createAddFolderCommand,\n createStoresCommand,\n createSuggestCommand,\n} from './cli/commands/plugin-api.js';\nimport { createSearchCommand } from './cli/commands/search.js';\nimport { createServeCommand } from './cli/commands/serve.js';\nimport { createSetupCommand } from './cli/commands/setup.js';\nimport { createStoreCommand } from './cli/commands/store.js';\nimport { createSyncCommand } from './cli/commands/sync.js';\nimport { createProgram, getGlobalOptions } from './cli/program.js';\n\n// Register built-in language adapters\nconst registry = AdapterRegistry.getInstance();\nregistry.register(new ZilAdapter());\n\n// Default paths (for help text display only - actual paths resolved by ConfigService)\nconst DEFAULT_DATA_DIR = '.bluera/bluera-knowledge/data';\nconst DEFAULT_CONFIG = '.bluera/bluera-knowledge/config.json';\nconst DEFAULT_REPOS_DIR = '.bluera/bluera-knowledge/data/repos/<store-id>/';\n\n/**\n * Format a command and its subcommands recursively for comprehensive help output.\n */\nfunction formatCommandHelp(cmd: Command, indent: string = ''): string[] {\n const lines: string[] = [];\n const name = cmd.name();\n const desc = cmd.description();\n const args = cmd.registeredArguments\n .map((a) => {\n const req = a.required;\n return req ? `<${a.name()}>` : `[${a.name()}]`;\n })\n .join(' ');\n\n // Command header with arguments\n lines.push(`${indent}${name}${args ? ` ${args}` : ''}`);\n if (desc) {\n lines.push(`${indent} ${desc}`);\n }\n\n // Options (skip -h, --help which is auto-added)\n const options = cmd.options.filter((o) => o.flags !== '-h, --help');\n for (const opt of options) {\n lines.push(`${indent} ${opt.flags.padEnd(28)} ${opt.description}`);\n }\n\n // Subcommands (recursive)\n const subcommands = cmd.commands.filter((c) => c.name() !== 'help');\n for (const sub of subcommands) {\n lines.push('');\n lines.push(...formatCommandHelp(sub, `${indent} `));\n }\n\n return lines;\n}\n\n/**\n * Print comprehensive help showing all commands, subcommands, and options.\n */\nfunction printFullHelp(program: Command): void {\n console.log('bluera-knowledge - CLI tool for managing knowledge stores with semantic search\\n');\n\n // Active paths\n console.log('Paths:');\n console.log(` data ${DEFAULT_DATA_DIR}`);\n console.log(` config ${DEFAULT_CONFIG}`);\n console.log(` repos ${DEFAULT_REPOS_DIR}`);\n\n // Global options\n console.log('\\nGlobal options:');\n const globalOpts = program.options.filter(\n (o) => o.flags !== '-h, --help' && o.flags !== '-V, --version'\n );\n for (const opt of globalOpts) {\n console.log(` ${opt.flags.padEnd(28)} ${opt.description}`);\n }\n\n console.log('\\nCommands:\\n');\n\n // All commands except help\n const commands = program.commands.filter((c) => c.name() !== 'help');\n for (const cmd of commands) {\n console.log(formatCommandHelp(cmd).join('\\n'));\n console.log('');\n }\n}\n\nconst program = createProgram();\n\n// Plugin API commands (simple interface)\nprogram.addCommand(createAddRepoCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createAddFolderCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createStoresCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSuggestCommand(() => getGlobalOptions(program)));\n\n// Advanced CLI commands\nprogram.addCommand(createStoreCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSearchCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createIndexCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createServeCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createCrawlCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSetupCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createSyncCommand(() => getGlobalOptions(program)));\nprogram.addCommand(createMCPCommand(() => getGlobalOptions(program)));\n\n// Show comprehensive help when no arguments provided\nif (process.argv.length <= 2) {\n printFullHelp(program);\n process.exit(0);\n}\n\nprogram.parse();\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA09Bd,SAAS,gBAAwB;AACtC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAME,WAAW,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["url","Command","ora","Command","ora","err","Command","Command","Command","ora","ora","Command","Command","Command","Command","join","join","fetch","err","Command","existsSync","join","Command","ora","join","Command","ora","existsSync","rm","join","Command","Command","join","rm","rm","join","Command","Command","join","rm","join","Command","__filename","__dirname","program","DEFAULT_REPOS_DIR","program"]}
|