brain-cache 0.4.2 → 2.1.0

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.
@@ -4,7 +4,7 @@ import {
4
4
  DEFAULT_EMBEDDING_DIMENSION,
5
5
  EMBED_TIMEOUT_MS,
6
6
  childLogger
7
- } from "./chunk-EEC7KYPY.js";
7
+ } from "./chunk-TXLCXXKY.js";
8
8
 
9
9
  // src/services/embedder.ts
10
10
  import ollama from "ollama";
@@ -18,13 +18,12 @@ var VECTOR_INDEX_THRESHOLD = 256;
18
18
  var EMBED_TIMEOUT_MS = 3e4;
19
19
  var COLD_START_RETRY_DELAY_MS = 2e3;
20
20
  var EMBED_MAX_TOKENS = 8192;
21
- var DEFAULT_SEARCH_LIMIT = 10;
22
- var DEFAULT_DISTANCE_THRESHOLD = 0.4;
23
- var DIAGNOSTIC_DISTANCE_THRESHOLD = 0.45;
24
- var DIAGNOSTIC_SEARCH_LIMIT = 20;
25
21
  var DEFAULT_TOKEN_BUDGET = 4096;
26
22
  var FILE_HASHES_FILENAME = "file-hashes.json";
27
23
  var TOOL_CALL_OVERHEAD_TOKENS = 300;
24
+ var COMPRESSION_TOKEN_THRESHOLD = 500;
25
+ var HIGH_RELEVANCE_SIMILARITY_THRESHOLD = 0.85;
26
+ var COMPRESSION_HARD_LIMIT = 800;
28
27
 
29
28
  // src/services/logger.ts
30
29
  import pino from "pino";
@@ -72,6 +71,7 @@ function setLogLevel(level) {
72
71
  export {
73
72
  GLOBAL_CONFIG_DIR,
74
73
  PROFILE_PATH,
74
+ CONFIG_PATH,
75
75
  PROJECT_DATA_DIR,
76
76
  EMBEDDING_DIMENSIONS,
77
77
  DEFAULT_EMBEDDING_DIMENSION,
@@ -81,13 +81,12 @@ export {
81
81
  EMBED_TIMEOUT_MS,
82
82
  COLD_START_RETRY_DELAY_MS,
83
83
  EMBED_MAX_TOKENS,
84
- DEFAULT_SEARCH_LIMIT,
85
- DEFAULT_DISTANCE_THRESHOLD,
86
- DIAGNOSTIC_DISTANCE_THRESHOLD,
87
- DIAGNOSTIC_SEARCH_LIMIT,
88
84
  DEFAULT_TOKEN_BUDGET,
89
85
  FILE_HASHES_FILENAME,
90
86
  TOOL_CALL_OVERHEAD_TOKENS,
87
+ COMPRESSION_TOKEN_THRESHOLD,
88
+ HIGH_RELEVANCE_SIMILARITY_THRESHOLD,
89
+ COMPRESSION_HARD_LIMIT,
91
90
  childLogger,
92
91
  setLogLevel
93
92
  };
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/claude-md-section.ts
4
+ var CLAUDE_MD_SECTION = `
5
+ ## Brain-Cache MCP Tools
6
+
7
+ Use brain-cache tools before reading files or using Grep/Glob for codebase questions.
8
+
9
+ | Query type | Tool | NOT this |
10
+ |-----------|------|---------|
11
+ | Locate a function, type, or symbol | \`search_codebase\` | \`build_context\` |
12
+ | Understand how specific code works across files | \`build_context\` | file reads |
13
+ | Trace a call path across files | \`trace_flow\` | \`build_context\` |
14
+ | Explain project architecture or structure | \`explain_codebase\` | \`build_context\` |
15
+ | Diagnose brain-cache failures | \`doctor\` | -- |
16
+ | Reindex the project | \`index_repo\` | -- |
17
+
18
+ ### search_codebase (locate code)
19
+
20
+ Call \`mcp__brain-cache__search_codebase\` to find functions, types, definitions, or implementations by meaning rather than keyword match.
21
+
22
+ Do NOT use for understanding how code works \u2014 use build_context once you have located the symbol.
23
+
24
+ ### build_context (understand specific behavior)
25
+
26
+ Call \`mcp__brain-cache__build_context\` with a focused question about how specific code works. It retrieves semantically relevant code, deduplicates results, and fits them to a token budget.
27
+
28
+ Use for: "How does X work?", "What does this function do?", debugging unfamiliar code paths.
29
+
30
+ Do NOT use for architecture overviews (use explain_codebase) or call-path tracing (use trace_flow).
31
+
32
+ ### trace_flow (trace call paths)
33
+
34
+ Call \`mcp__brain-cache__trace_flow\` to trace how a function call propagates through the codebase. Returns structured hops showing the call chain across files.
35
+
36
+ Use for: "How does X flow to Y?", "Trace how X calls Y across files", "What happens when X is called?", "Call path from X to Y".
37
+
38
+ Do NOT use for code understanding queries like "how does X work" or "what does X do" \u2014 use build_context instead.
39
+
40
+ Use trace_flow instead of build_context when the question is about call propagation or execution flow across files.
41
+
42
+ ### explain_codebase (architecture overview)
43
+
44
+ Call \`mcp__brain-cache__explain_codebase\` to get a module-grouped architecture overview. No follow-up question needed.
45
+
46
+ Use for: "Explain the project architecture", "How is this project structured?", "What does this project do?", "Give me an overview of the codebase".
47
+
48
+ Do NOT use for questions about specific code behavior or how a particular function works \u2014 use build_context instead.
49
+
50
+ Use explain_codebase instead of build_context when the question is about overall structure or getting oriented.
51
+
52
+ ### doctor (diagnose issues)
53
+
54
+ Call \`mcp__brain-cache__doctor\` when any brain-cache tool fails or returns unexpected results.
55
+
56
+ ### index_repo (reindex)
57
+
58
+ Call \`mcp__brain-cache__index_repo\` only when the user explicitly asks to reindex, or after major code changes. Do not call proactively.
59
+ `;
60
+ export {
61
+ CLAUDE_MD_SECTION
62
+ };
package/dist/cli.js CHANGED
@@ -1,27 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  formatTokenSavings
4
- } from "./chunk-ZGYLHFHJ.js";
4
+ } from "./chunk-6C2OYMKD.js";
5
5
 
6
6
  // src/cli/index.ts
7
7
  import { Command } from "commander";
8
- var version = "0.4.2";
8
+ var version = true ? "2.1.0" : "dev";
9
9
  var program = new Command();
10
10
  program.name("brain-cache").description("Local AI runtime \u2014 GPU cache layer for Claude").version(version);
11
11
  program.command("init").description("Detect hardware, pull embedding model, create config directory").action(async () => {
12
- const { runInit } = await import("./init-QNN5H3DR.js");
12
+ const { runInit } = await import("./init-BCMT64T2.js");
13
13
  await runInit();
14
14
  });
15
15
  program.command("doctor").description("Report system health: GPU, VRAM tier, Ollama status").action(async () => {
16
- const { runDoctor } = await import("./doctor-KRNLXE4R.js");
16
+ const { runDoctor } = await import("./doctor-FCET2MNJ.js");
17
17
  await runDoctor();
18
18
  });
19
19
  program.command("index").description("Index a codebase: parse, chunk, embed, and store in LanceDB").argument("[path]", "Directory to index (defaults to current directory)").option("-f, --force", "Force full reindex, ignoring cached file hashes").action(async (path, opts) => {
20
- const { runIndex } = await import("./workflows-KYCBR7TC.js");
20
+ const { runIndex } = await import("./workflows-MWEY7OAI.js");
21
21
  await runIndex(path, { force: opts.force });
22
22
  });
23
+ program.command("watch").description("Watch a directory for file changes and auto-reindex").argument("[path]", "Directory to watch (defaults to current directory)").action(async (path) => {
24
+ const { runWatch } = await import("./watch-QPMAB62P.js");
25
+ await runWatch(path);
26
+ });
23
27
  program.command("search").description("Search indexed codebase with a natural language query").argument("<query>", "Natural language query string").option("-n, --limit <n>", "Maximum number of results", "10").option("-p, --path <path>", "Project root directory").action(async (query, opts) => {
24
- const { runSearch } = await import("./search-O4CFAH45.js");
28
+ const { runSearch } = await import("./search-7ISZ7EXI.js");
25
29
  await runSearch(query, {
26
30
  limit: parseInt(opts.limit, 10),
27
31
  path: opts.path
@@ -30,12 +34,12 @@ program.command("search").description("Search indexed codebase with a natural la
30
34
  program.command("status").description(
31
35
  "Show index stats: files indexed, chunks stored, last indexed time"
32
36
  ).argument("[path]", "Project root directory (defaults to current directory)").action(async (path) => {
33
- const { runStatus } = await import("./status-7MT4IROA.js");
37
+ const { runStatus } = await import("./status-VKTSG2SN.js");
34
38
  await runStatus(path);
35
39
  });
36
40
  program.command("context").description("Build token-budgeted context from codebase for a query").argument("<query>", "Natural language query string").option("-n, --limit <n>", "Maximum number of search results", "10").option("-b, --budget <tokens>", "Token budget for assembled context", "4096").option("-p, --path <path>", "Project root directory").option("--raw", "Output raw JSON (MCP transport compatible)").action(
37
41
  async (query, opts) => {
38
- const { runBuildContext } = await import("./buildContext-APWOPZMJ.js");
42
+ const { runBuildContext } = await import("./buildContext-GWVDAYH6.js");
39
43
  const result = await runBuildContext(query, {
40
44
  limit: parseInt(opts.limit, 10),
41
45
  maxTokens: parseInt(opts.budget, 10),
@@ -60,7 +64,7 @@ ${formatTokenSavings({ tokensSent: result.metadata.tokensSent, estimatedWithout:
60
64
  program.command("ask").description(
61
65
  "Ask a natural language question about the codebase \u2014 retrieves context locally, reasons via Claude"
62
66
  ).argument("<question>", "Natural language question about the codebase").option("-b, --budget <tokens>", "Token budget for context retrieval", "4096").option("-p, --path <path>", "Project root directory").action(async (question, opts) => {
63
- const { runAskCodebase } = await import("./askCodebase-BZIXS3EV.js");
67
+ const { runAskCodebase } = await import("./askCodebase-EE32B7BP.js");
64
68
  const result = await runAskCodebase(question, {
65
69
  path: opts.path,
66
70
  maxContextTokens: parseInt(opts.budget, 10)
@@ -4,14 +4,14 @@ import {
4
4
  isOllamaInstalled,
5
5
  isOllamaRunning,
6
6
  modelMatches
7
- } from "./chunk-FQL4HV4R.js";
7
+ } from "./chunk-HRJ3OT6Q.js";
8
8
  import {
9
9
  detectCapabilities,
10
10
  readProfile
11
- } from "./chunk-PJQNHMQH.js";
11
+ } from "./chunk-DPH5X5HL.js";
12
12
  import {
13
13
  PROFILE_PATH
14
- } from "./chunk-EEC7KYPY.js";
14
+ } from "./chunk-TXLCXXKY.js";
15
15
 
16
16
  // src/workflows/doctor.ts
17
17
  import ollama from "ollama";
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  embedBatch,
4
4
  embedBatchWithRetry
5
- } from "./chunk-KQZSBRRH.js";
6
- import "./chunk-EEC7KYPY.js";
5
+ } from "./chunk-RKPICQU7.js";
6
+ import "./chunk-TXLCXXKY.js";
7
7
  export {
8
8
  embedBatch,
9
9
  embedBatchWithRetry
@@ -5,15 +5,17 @@ import {
5
5
  isOllamaRunning,
6
6
  pullModelIfMissing,
7
7
  startOllama
8
- } from "./chunk-FQL4HV4R.js";
8
+ } from "./chunk-HRJ3OT6Q.js";
9
9
  import {
10
10
  detectCapabilities,
11
11
  writeProfile
12
- } from "./chunk-PJQNHMQH.js";
13
- import "./chunk-EEC7KYPY.js";
12
+ } from "./chunk-DPH5X5HL.js";
13
+ import "./chunk-TXLCXXKY.js";
14
14
 
15
15
  // src/workflows/init.ts
16
- import { existsSync, readFileSync, writeFileSync, appendFileSync } from "fs";
16
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, chmodSync, mkdirSync } from "fs";
17
+ import { join } from "path";
18
+ import { homedir } from "os";
17
19
  async function runInit() {
18
20
  process.stderr.write("brain-cache: detecting hardware capabilities...\n");
19
21
  const profile = await detectCapabilities();
@@ -52,7 +54,7 @@ async function runInit() {
52
54
  `brain-cache: warming model ${profileWithVersion.embeddingModel} into VRAM...
53
55
  `
54
56
  );
55
- const { embedBatchWithRetry } = await import("./embedder-ZLHAZZUI.js");
57
+ const { embedBatchWithRetry } = await import("./embedder-HVEXDJAU.js");
56
58
  await embedBatchWithRetry(profileWithVersion.embeddingModel, ["warmup"]);
57
59
  process.stderr.write("brain-cache: model warm.\n");
58
60
  await writeProfile(profileWithVersion);
@@ -86,7 +88,7 @@ async function runInit() {
86
88
  process.stderr.write("brain-cache: created .mcp.json with brain-cache MCP server.\n");
87
89
  }
88
90
  const claudeMdPath = "CLAUDE.md";
89
- const { CLAUDE_MD_SECTION: brainCacheSection } = await import("./claude-md-section-6ZJ3TMO4.js");
91
+ const { CLAUDE_MD_SECTION: brainCacheSection } = await import("./claude-md-section-O5LMKH4O.js");
90
92
  if (existsSync(claudeMdPath)) {
91
93
  const content = readFileSync(claudeMdPath, "utf-8");
92
94
  if (content.includes("## Brain-Cache MCP Tools")) {
@@ -99,6 +101,54 @@ async function runInit() {
99
101
  writeFileSync(claudeMdPath, brainCacheSection.trimStart());
100
102
  process.stderr.write("brain-cache: created CLAUDE.md with Brain-Cache MCP Tools section.\n");
101
103
  }
104
+ const { STATUSLINE_SCRIPT_CONTENT } = await import("./statusline-script-NFUDFOWK.js");
105
+ const statuslinePath = join(homedir(), ".brain-cache", "statusline.mjs");
106
+ if (existsSync(statuslinePath)) {
107
+ const existingScript = readFileSync(statuslinePath, "utf-8");
108
+ if (existingScript === STATUSLINE_SCRIPT_CONTENT) {
109
+ process.stderr.write("brain-cache: statusline.mjs already installed, skipping.\n");
110
+ } else {
111
+ process.stderr.write(
112
+ "brain-cache: Warning: ~/.brain-cache/statusline.mjs already exists with custom content. Skipping to preserve user changes.\n"
113
+ );
114
+ }
115
+ } else {
116
+ writeFileSync(statuslinePath, STATUSLINE_SCRIPT_CONTENT, "utf-8");
117
+ chmodSync(statuslinePath, 493);
118
+ process.stderr.write("brain-cache: installed statusline.mjs to ~/.brain-cache/statusline.mjs\n");
119
+ }
120
+ const claudeDir = join(homedir(), ".claude");
121
+ const settingsPath = join(claudeDir, "settings.json");
122
+ const statusLineEntry = {
123
+ type: "command",
124
+ command: `node "${join(homedir(), ".brain-cache", "statusline.mjs")}"`
125
+ };
126
+ try {
127
+ if (existsSync(settingsPath)) {
128
+ const rawSettings = readFileSync(settingsPath, "utf-8");
129
+ const parsed = JSON.parse(rawSettings);
130
+ if (parsed["statusLine"]) {
131
+ process.stderr.write(
132
+ "brain-cache: Warning: ~/.claude/settings.json already has a statusLine entry. Skipping to preserve existing configuration.\n"
133
+ );
134
+ } else {
135
+ parsed["statusLine"] = statusLineEntry;
136
+ writeFileSync(settingsPath, JSON.stringify(parsed, null, 2) + "\n");
137
+ process.stderr.write("brain-cache: added statusLine to ~/.claude/settings.json\n");
138
+ }
139
+ } else {
140
+ mkdirSync(claudeDir, { recursive: true });
141
+ const newSettings = { statusLine: statusLineEntry };
142
+ writeFileSync(settingsPath, JSON.stringify(newSettings, null, 2) + "\n");
143
+ process.stderr.write("brain-cache: created ~/.claude/settings.json with statusLine entry.\n");
144
+ }
145
+ } catch (err) {
146
+ const msg = err instanceof Error ? err.message : String(err);
147
+ process.stderr.write(
148
+ `brain-cache: Warning: Could not configure ~/.claude/settings.json: ${msg}. Status line will not appear in Claude Code until settings.json is configured manually.
149
+ `
150
+ );
151
+ }
102
152
  }
103
153
  export {
104
154
  runInit