@nxuss/lemma 1.3.3 → 1.4.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.
Files changed (56) hide show
  1. package/README.md +31 -2
  2. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  3. package/dist/cjs/mcp/tools.js +112 -71
  4. package/dist/cjs/mcp/tools.js.map +1 -1
  5. package/dist/cjs/subconscious/TheBrainV2.d.ts +4 -1
  6. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
  7. package/dist/cjs/subconscious/TheBrainV2.js +49 -9
  8. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
  9. package/dist/cjs/utils/PatchMatcher.d.ts +17 -0
  10. package/dist/cjs/utils/PatchMatcher.d.ts.map +1 -0
  11. package/dist/cjs/utils/PatchMatcher.js +210 -0
  12. package/dist/cjs/utils/PatchMatcher.js.map +1 -0
  13. package/dist/cjs/utils/ReadWorkspaceCache.d.ts +9 -0
  14. package/dist/cjs/utils/ReadWorkspaceCache.d.ts.map +1 -0
  15. package/dist/cjs/utils/ReadWorkspaceCache.js +31 -0
  16. package/dist/cjs/utils/ReadWorkspaceCache.js.map +1 -0
  17. package/dist/cjs/utils/SearchCache.d.ts +7 -0
  18. package/dist/cjs/utils/SearchCache.d.ts.map +1 -0
  19. package/dist/cjs/utils/SearchCache.js +75 -0
  20. package/dist/cjs/utils/SearchCache.js.map +1 -0
  21. package/dist/cjs/utils/StructuralSearch.d.ts +18 -0
  22. package/dist/cjs/utils/StructuralSearch.d.ts.map +1 -0
  23. package/dist/cjs/utils/StructuralSearch.js +190 -0
  24. package/dist/cjs/utils/StructuralSearch.js.map +1 -0
  25. package/dist/cjs/utils/WorkspaceSearch.d.ts +20 -0
  26. package/dist/cjs/utils/WorkspaceSearch.d.ts.map +1 -0
  27. package/dist/cjs/utils/WorkspaceSearch.js +0 -0
  28. package/dist/cjs/utils/WorkspaceSearch.js.map +1 -0
  29. package/dist/esm/mcp/tools.d.ts.map +1 -1
  30. package/dist/esm/mcp/tools.js +112 -71
  31. package/dist/esm/mcp/tools.js.map +1 -1
  32. package/dist/esm/subconscious/TheBrainV2.d.ts +4 -1
  33. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
  34. package/dist/esm/subconscious/TheBrainV2.js +49 -9
  35. package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
  36. package/dist/esm/utils/PatchMatcher.d.ts +17 -0
  37. package/dist/esm/utils/PatchMatcher.d.ts.map +1 -0
  38. package/dist/esm/utils/PatchMatcher.js +205 -0
  39. package/dist/esm/utils/PatchMatcher.js.map +1 -0
  40. package/dist/esm/utils/ReadWorkspaceCache.d.ts +9 -0
  41. package/dist/esm/utils/ReadWorkspaceCache.d.ts.map +1 -0
  42. package/dist/esm/utils/ReadWorkspaceCache.js +24 -0
  43. package/dist/esm/utils/ReadWorkspaceCache.js.map +1 -0
  44. package/dist/esm/utils/SearchCache.d.ts +7 -0
  45. package/dist/esm/utils/SearchCache.d.ts.map +1 -0
  46. package/dist/esm/utils/SearchCache.js +67 -0
  47. package/dist/esm/utils/SearchCache.js.map +1 -0
  48. package/dist/esm/utils/StructuralSearch.d.ts +18 -0
  49. package/dist/esm/utils/StructuralSearch.d.ts.map +1 -0
  50. package/dist/esm/utils/StructuralSearch.js +150 -0
  51. package/dist/esm/utils/StructuralSearch.js.map +1 -0
  52. package/dist/esm/utils/WorkspaceSearch.d.ts +20 -0
  53. package/dist/esm/utils/WorkspaceSearch.d.ts.map +1 -0
  54. package/dist/esm/utils/WorkspaceSearch.js +0 -0
  55. package/dist/esm/utils/WorkspaceSearch.js.map +1 -0
  56. package/package.json +1 -1
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isStructurallySearchable = isStructurallySearchable;
40
+ exports.resolveStructuralMatches = resolveStructuralMatches;
41
+ const fs_1 = __importDefault(require("fs"));
42
+ const ts = __importStar(require("typescript"));
43
+ const SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts"];
44
+ function isStructurallySearchable(filePath) {
45
+ return SUPPORTED_EXTENSIONS.some((ext) => filePath.endsWith(ext));
46
+ }
47
+ function oneLineSignature(text) {
48
+ return text.replace(/\s+/g, " ").trim();
49
+ }
50
+ function collectDeclarations(sourceFile) {
51
+ const declarations = [];
52
+ function lineOf(pos) {
53
+ return sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
54
+ }
55
+ function addFromFunctionLike(node, name, kind) {
56
+ const start = node.getStart(sourceFile);
57
+ const end = node.body ? node.body.getStart(sourceFile) : node.getEnd();
58
+ let sig = sourceFile.text.substring(start, end).trim();
59
+ if (sig.endsWith("{"))
60
+ sig = sig.slice(0, -1).trim();
61
+ declarations.push({ kind, name, signature: oneLineSignature(sig), startLine: lineOf(node.getStart(sourceFile)), endLine: lineOf(node.getEnd()) });
62
+ }
63
+ function visit(node) {
64
+ if (ts.isFunctionDeclaration(node) && node.name) {
65
+ addFromFunctionLike(node, node.name.text, "function");
66
+ }
67
+ else if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name)) {
68
+ addFromFunctionLike(node, node.name.text, "method");
69
+ }
70
+ else if (ts.isClassDeclaration(node) && node.name) {
71
+ declarations.push({
72
+ kind: "class",
73
+ name: node.name.text,
74
+ signature: `class ${node.name.text}`,
75
+ startLine: lineOf(node.getStart(sourceFile)),
76
+ endLine: lineOf(node.getEnd()),
77
+ });
78
+ }
79
+ else if (ts.isInterfaceDeclaration(node)) {
80
+ declarations.push({
81
+ kind: "interface",
82
+ name: node.name.text,
83
+ signature: `interface ${node.name.text}`,
84
+ startLine: lineOf(node.getStart(sourceFile)),
85
+ endLine: lineOf(node.getEnd()),
86
+ });
87
+ }
88
+ else if (ts.isTypeAliasDeclaration(node)) {
89
+ declarations.push({
90
+ kind: "type",
91
+ name: node.name.text,
92
+ signature: oneLineSignature(node.getText(sourceFile).split("=")[0] + "= ..."),
93
+ startLine: lineOf(node.getStart(sourceFile)),
94
+ endLine: lineOf(node.getEnd()),
95
+ });
96
+ }
97
+ else if (ts.isEnumDeclaration(node)) {
98
+ declarations.push({
99
+ kind: "enum",
100
+ name: node.name.text,
101
+ signature: `enum ${node.name.text}`,
102
+ startLine: lineOf(node.getStart(sourceFile)),
103
+ endLine: lineOf(node.getEnd()),
104
+ });
105
+ }
106
+ else if (ts.isVariableStatement(node) &&
107
+ node.declarationList.declarations.length === 1 &&
108
+ ts.isIdentifier(node.declarationList.declarations[0].name) &&
109
+ node.declarationList.declarations[0].initializer &&
110
+ (ts.isArrowFunction(node.declarationList.declarations[0].initializer) || ts.isFunctionExpression(node.declarationList.declarations[0].initializer))) {
111
+ const decl = node.declarationList.declarations[0];
112
+ const fn = decl.initializer;
113
+ const start = node.getStart(sourceFile);
114
+ const end = fn.body.getStart(sourceFile);
115
+ let sig = sourceFile.text.substring(start, end).trim();
116
+ if (sig.endsWith("{"))
117
+ sig = sig.slice(0, -1).trim();
118
+ declarations.push({
119
+ kind: "arrow",
120
+ name: decl.name.text,
121
+ signature: oneLineSignature(sig),
122
+ startLine: lineOf(node.getStart(sourceFile)),
123
+ endLine: lineOf(node.getEnd()),
124
+ });
125
+ }
126
+ ts.forEachChild(node, visit);
127
+ }
128
+ visit(sourceFile);
129
+ return declarations;
130
+ }
131
+ function scriptKindFor(filePath) {
132
+ if (filePath.endsWith(".tsx"))
133
+ return ts.ScriptKind.TSX;
134
+ if (filePath.endsWith(".jsx"))
135
+ return ts.ScriptKind.JSX;
136
+ if (filePath.endsWith(".js") || filePath.endsWith(".cts") || filePath.endsWith(".mts"))
137
+ return ts.ScriptKind.JS;
138
+ return ts.ScriptKind.TS;
139
+ }
140
+ // Collapses raw line matches into the enclosing symbol they fall within, so a query
141
+ // matching many lines inside the same function reports one symbol entry instead of
142
+ // N separate lines. Matches outside any declaration (imports, top-level statements,
143
+ // comments) are returned separately as "unscoped" line hits.
144
+ function resolveStructuralMatches(fullPath, relativePath, matches) {
145
+ if (!isStructurallySearchable(relativePath))
146
+ return null;
147
+ let sourceText;
148
+ try {
149
+ sourceText = fs_1.default.readFileSync(fullPath, "utf8");
150
+ }
151
+ catch {
152
+ return null;
153
+ }
154
+ let sourceFile;
155
+ try {
156
+ sourceFile = ts.createSourceFile(fullPath, sourceText, ts.ScriptTarget.Latest, true, scriptKindFor(relativePath));
157
+ }
158
+ catch {
159
+ return null;
160
+ }
161
+ const declarations = collectDeclarations(sourceFile);
162
+ if (declarations.length === 0)
163
+ return null;
164
+ const bySymbol = new Map();
165
+ const unscoped = [];
166
+ for (const match of matches) {
167
+ // innermost enclosing declaration = smallest range containing the match line
168
+ let best = null;
169
+ for (const d of declarations) {
170
+ if (match.line >= d.startLine && match.line <= d.endLine) {
171
+ if (!best || d.endLine - d.startLine < best.endLine - best.startLine)
172
+ best = d;
173
+ }
174
+ }
175
+ if (!best) {
176
+ unscoped.push(match);
177
+ continue;
178
+ }
179
+ const key = `${best.kind}:${best.name}:${best.startLine}`;
180
+ const existing = bySymbol.get(key);
181
+ if (existing) {
182
+ existing.matchLines.push(match.line);
183
+ }
184
+ else {
185
+ bySymbol.set(key, { symbol: best, matchLines: [match.line] });
186
+ }
187
+ }
188
+ return { symbolHits: [...bySymbol.values()], unscoped };
189
+ }
190
+ //# sourceMappingURL=StructuralSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StructuralSearch.js","sourceRoot":"","sources":["../../../src/utils/StructuralSearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SearchMatch {
2
+ filePath: string;
3
+ line: number;
4
+ text: string;
5
+ }
6
+ export interface GroupedSearchResult {
7
+ totalMatches: number;
8
+ filesMatched: number;
9
+ truncated: boolean;
10
+ formatted: string;
11
+ }
12
+ export declare function loadGitignorePatterns(workspaceRoot: string): RegExp[];
13
+ export declare function parseExtensionFilter(extension?: string): string[] | undefined;
14
+ export interface SearchWorkspaceResult {
15
+ matches: SearchMatch[];
16
+ truncated: boolean;
17
+ }
18
+ export declare function searchWorkspace(workspaceRoot: string, query: string, extensions?: string[], maxResults?: number): SearchWorkspaceResult;
19
+ export declare function groupSearchResults(matches: SearchMatch[], truncated: boolean, maxPerFile?: number, workspaceRoot?: string): GroupedSearchResult;
20
+ //# sourceMappingURL=WorkspaceSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceSearch.d.ts","sourceRoot":"","sources":["../../../src/utils/WorkspaceSearch.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAwBD,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAYrE;AAcD,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAM7E;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,UAAU,SAAsB,GAC/B,qBAAqB,CAiEvB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,EAAE,EACtB,SAAS,EAAE,OAAO,EAClB,UAAU,SAAuB,EACjC,aAAa,CAAC,EAAE,MAAM,GACrB,mBAAmB,CA6BrB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceSearch.js","sourceRoot":"","sources":["../../../src/utils/WorkspaceSearch.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAwiCnE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CA2DN"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA+iCnE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CA2DN"}
@@ -33,6 +33,10 @@ import { surgicalASTInsert } from "../utils/SurgicalASTInsert";
33
33
  import { getInfraToolDefinitions, getInfraToolHandlers, INFRA_TOOL_NAMES } from "../infra/mcp-tools";
34
34
  import { lookupStateHash, storeStateHash } from "../utils/StateHashCache";
35
35
  import { recordReceiptEvent, getReceiptSummary } from "../utils/TokenReceipt";
36
+ import { findMatch, reindentReplacement } from "../utils/PatchMatcher";
37
+ import { searchWorkspace, groupSearchResults, parseExtensionFilter } from "../utils/WorkspaceSearch";
38
+ import { checkAlreadySent, recordSent } from "../utils/ReadWorkspaceCache";
39
+ import { getCachedSearch, setCachedSearch } from "../utils/SearchCache";
36
40
  // ── Pro License Gate ──────────────────────────────────────────────────────────
37
41
  const LICENSE_FILE = path.join(os.homedir(), '.lemma-cache', 'license.json');
38
42
  let _proStatusCache = null;
@@ -89,7 +93,7 @@ const toolDefinitions = [
89
93
  },
90
94
  {
91
95
  name: "search_memory",
92
- description: "Search Lemma's semantic memory (The Brain) before answering technical questions. Retrieves past solutions, fixes, and context from ALL your projects globally. If similarity > 50%, use this answer directly.",
96
+ description: "Search Lemma's semantic memory (The Brain) before investigating something from scratch — retrieves past solutions, fixes, and context from ALL your projects globally. Results are split into 'fresh' (safe to reuse — either untracked general knowledge, or every file it depended on still hashes the same) and 'stale' (a similar question was answered before, but a tracked file changed since — re-verify against current state before reusing). Never treat a stale result as current.",
93
97
  inputSchema: {
94
98
  type: "object",
95
99
  properties: {
@@ -101,13 +105,14 @@ const toolDefinitions = [
101
105
  },
102
106
  {
103
107
  name: "store_memory",
104
- description: "Persist a technical solution, bug fix, architecture decision, or key fact into Lemma's Brain.",
108
+ description: "Persist a technical solution, bug fix, architecture decision, or key fact into Lemma's Brain — so future questions on the same topic (even phrased differently) don't require re-investigating the repo. Pass filePaths for anything derived from specific files (e.g. 'where is X implemented', 'how does Y work') so the memory auto-invalidates the moment those files change, instead of risking a stale answer being reused.",
105
109
  inputSchema: {
106
110
  type: "object",
107
111
  properties: {
108
112
  query: { type: "string", description: "The natural language query key" },
109
113
  response: { type: "string", description: "The complete technical content to memorize" },
110
114
  provider: { type: "string", description: "Optional model provider name", default: "generic" },
115
+ filePaths: { type: "array", items: { type: "string" }, description: "Paths (relative to project root) this answer depends on. If any changes later, this memory is marked stale instead of being silently reused." },
111
116
  },
112
117
  required: ["query", "response"],
113
118
  },
@@ -136,12 +141,13 @@ const toolDefinitions = [
136
141
  },
137
142
  {
138
143
  name: "read_workspace_file",
139
- description: "Read a file inside the workspace. Automatically compresses comments/whitespace and scrubs API keys.",
144
+ description: "Read a file inside the workspace. Automatically compresses comments/whitespace and scrubs API keys. If this exact file (same compact mode) was already read this session and hasn't changed on disk, returns a short UNCHANGED marker instead of resending the full content — reuse your existing copy. Pass force:true to always get the full content.",
140
145
  inputSchema: {
141
146
  type: "object",
142
147
  properties: {
143
148
  filePath: { type: "string", description: "Path relative to the project root" },
144
149
  compact: { type: "boolean", description: "Whether to compress comments and whitespace", default: true },
150
+ force: { type: "boolean", description: "Bypass the unchanged-file short-circuit and always return full content", default: false },
145
151
  },
146
152
  required: ["filePath"],
147
153
  },
@@ -172,7 +178,7 @@ const toolDefinitions = [
172
178
  },
173
179
  {
174
180
  name: "apply_workspace_patch",
175
- description: "Apply a smart search-and-replace patch to an existing file. Safe against duplicate matches.",
181
+ description: "Apply a smart search-and-replace patch to an existing file. Falls back through whitespace-normalized, indent-anchored, and fuzzy matching if the exact block isn't found — so a searchContent built from a compacted read still applies. Safe against duplicate matches. On total failure, the error includes a diff against the closest candidate block.",
176
182
  inputSchema: {
177
183
  type: "object",
178
184
  properties: {
@@ -207,12 +213,13 @@ const toolDefinitions = [
207
213
  },
208
214
  {
209
215
  name: "search_workspace",
210
- description: "Perform a fast local text search (grep) across all files in the project workspace.",
216
+ description: "Perform a fast local text search (grep) across all files in the project workspace. Respects .gitignore, skips binaries and files over 500KB, groups results by file (capped per file), and stops at maxResults. For code files (.ts/.tsx/.js/.jsx), matches inside the same function/class/method are collapsed into one entry with its signature and line range instead of raw duplicate lines. Repeating an identical query while the workspace is unchanged returns the cached result instantly instead of re-scanning.",
211
217
  inputSchema: {
212
218
  type: "object",
213
219
  properties: {
214
220
  query: { type: "string", description: "The keyword or text pattern to search for" },
215
- extension: { type: "string", description: "Optional file extension filter (e.g., 'ts', 'json')" },
221
+ extension: { type: "string", description: "Optional file extension filter, comma-separated for multiple (e.g., 'ts,tsx')" },
222
+ maxResults: { type: "number", description: "Maximum total matches to return before truncating", default: 200 },
216
223
  },
217
224
  required: ["query"],
218
225
  },
@@ -1113,12 +1120,27 @@ async function handleSearchMemory(args) {
1113
1120
  if (results.length === 0) {
1114
1121
  return { content: [{ type: "text", text: "No relevant memories found in Lemma's Brain." }] };
1115
1122
  }
1116
- const formatted = results
1117
- .map((r, i) => {
1118
- return `Result ${i + 1} (Similarity: ${(r.similarity * 100).toFixed(1)}%)\nPrompt: ${r.query.substring(0, 300)}...\nResponse: ${typeof r.response === "string" ? r.response : JSON.stringify(r.response, null, 2)}`;
1119
- })
1120
- .join("\n\n---\n\n");
1121
- return { content: [{ type: "text", text: `Lemma found ${results.length} memories:\n\n${formatted}` }] };
1123
+ const fresh = results.filter((r) => r.fresh);
1124
+ const stale = results.filter((r) => !r.fresh);
1125
+ const formatResult = (r, i) => `Result ${i + 1} (Similarity: ${(r.similarity * 100).toFixed(1)}%)\nPrompt: ${r.query.substring(0, 300)}...\nResponse: ${typeof r.response === "string" ? r.response : JSON.stringify(r.response, null, 2)}`;
1126
+ if (fresh.length > 0) {
1127
+ // Only a fresh hit (or an untracked, purely conceptual entry) counts as a real
1128
+ // avoided re-investigation this is the only case worth crediting as savings.
1129
+ const bestFresh = fresh[0];
1130
+ const tokensSaved = Math.max(100, Math.floor(String(bestFresh.response).length / 4));
1131
+ reportSavings({ source: "cache", tokens: tokensSaved, toolName: "search_memory", query: query.substring(0, 100) });
1132
+ }
1133
+ const parts = [];
1134
+ if (fresh.length > 0) {
1135
+ parts.push(`Lemma found ${fresh.length} fresh ${fresh.length === 1 ? "memory" : "memories"} (from cache — say so if you use this):\n\n${fresh.map(formatResult).join("\n\n---\n\n")}`);
1136
+ }
1137
+ if (stale.length > 0) {
1138
+ const staleText = stale
1139
+ .map((r, i) => `${formatResult(r, i)}\nSTALE — changed since stored: ${r.staleFiles.join(", ")}`)
1140
+ .join("\n\n---\n\n");
1141
+ parts.push(`${stale.length} more ${stale.length === 1 ? "memory is" : "memories are"} similar but STALE (underlying file(s) changed) — do not reuse verbatim, re-verify against current file state:\n\n${staleText}`);
1142
+ }
1143
+ return { content: [{ type: "text", text: parts.join("\n\n===\n\n") }] };
1122
1144
  }
1123
1145
  catch (e) {
1124
1146
  logError("search_memory", e);
@@ -1129,11 +1151,12 @@ async function handleStoreMemory(args) {
1129
1151
  const query = args?.query;
1130
1152
  const responseText = args?.response;
1131
1153
  const provider = args?.provider || "generic";
1154
+ const filePaths = Array.isArray(args?.filePaths) ? args.filePaths : undefined;
1132
1155
  if (!query || !responseText)
1133
1156
  throw new Error("Query and response are required");
1134
1157
  try {
1135
1158
  const brain = getBrain();
1136
- const storeRes = brain.store(query, responseText, provider);
1159
+ const storeRes = brain.store(query, responseText, provider, 0.92, filePaths);
1137
1160
  const tokensSaved = Math.max(100, Math.floor(responseText.length / 4));
1138
1161
  reportSavings({
1139
1162
  source: "cache",
@@ -1141,7 +1164,8 @@ async function handleStoreMemory(args) {
1141
1164
  toolName: "store_memory",
1142
1165
  query: query.substring(0, 100),
1143
1166
  });
1144
- return { content: [{ type: "text", text: `Success: Memory stored. ${storeRes.reason}` }] };
1167
+ const trackingNote = filePaths && filePaths.length > 0 ? ` Tracking freshness against ${filePaths.length} file(s) — this memory auto-invalidates if they change.` : "";
1168
+ return { content: [{ type: "text", text: `Success: Memory stored. ${storeRes.reason}${trackingNote}` }] };
1145
1169
  }
1146
1170
  catch (e) {
1147
1171
  logError("store_memory", e);
@@ -1186,6 +1210,7 @@ async function handleAutoHeal(args) {
1186
1210
  async function handleReadWorkspaceFile(args) {
1187
1211
  const filePath = args?.filePath;
1188
1212
  const compact = args?.compact !== false;
1213
+ const force = !!args?.force;
1189
1214
  if (!filePath)
1190
1215
  throw new Error("filePath is required");
1191
1216
  const workspaceRoot = process.cwd();
@@ -1193,6 +1218,24 @@ async function handleReadWorkspaceFile(args) {
1193
1218
  const { resolved } = safeResolvePath(workspaceRoot, filePath);
1194
1219
  let content = fs.readFileSync(resolved, "utf8");
1195
1220
  const originalSize = content.length;
1221
+ const dedup = checkAlreadySent(resolved, compact, content);
1222
+ if (!force && dedup.unchanged) {
1223
+ reportSavings({
1224
+ source: "contextSqueeze",
1225
+ charsBefore: originalSize,
1226
+ charsAfter: 0,
1227
+ toolName: "read_workspace_file",
1228
+ filePath,
1229
+ });
1230
+ return {
1231
+ content: [
1232
+ {
1233
+ type: "text",
1234
+ text: `UNCHANGED: ${filePath} is identical to what you already read this session (hash ${dedup.hash.slice(0, 12)}) — reuse your existing copy. Pass force:true to re-fetch anyway.`,
1235
+ },
1236
+ ],
1237
+ };
1238
+ }
1196
1239
  if (compact) {
1197
1240
  content = squeezeCode(content);
1198
1241
  if (content.length < originalSize) {
@@ -1213,6 +1256,7 @@ async function handleReadWorkspaceFile(args) {
1213
1256
  catch (err) {
1214
1257
  logWarn("read_workspace_file", "SemanticScrubber failed, returning raw content");
1215
1258
  }
1259
+ recordSent(resolved, compact, dedup.hash);
1216
1260
  return { content: [{ type: "text", text: content }] };
1217
1261
  }
1218
1262
  catch (err) {
@@ -1279,30 +1323,44 @@ async function handleApplyWorkspacePatch(args) {
1279
1323
  return { content: [{ type: "text", text: `Error: File ${filePath} does not exist.` }] };
1280
1324
  }
1281
1325
  const originalContent = fs.readFileSync(resolved, "utf8");
1282
- const index = originalContent.indexOf(searchContent);
1283
- if (index === -1) {
1284
- return {
1285
- content: [
1286
- {
1287
- type: "text",
1288
- text: `Error: Target search content not found in file. Make sure the search content matches exactly, including indentation, tabs, spaces, and newlines.`,
1289
- },
1290
- ],
1291
- };
1292
- }
1293
- if (originalContent.indexOf(searchContent, index + 1) !== -1) {
1326
+ const matchResult = findMatch(originalContent, searchContent);
1327
+ if (!Array.isArray(matchResult)) {
1328
+ if (matchResult.reason === "ambiguous") {
1329
+ return {
1330
+ content: [
1331
+ {
1332
+ type: "text",
1333
+ text: `Error: Multiple matches found for the search content. Please provide a larger search block with unique surrounding context lines to make it unambiguous.`,
1334
+ },
1335
+ ],
1336
+ };
1337
+ }
1338
+ if (matchResult.candidateDiff) {
1339
+ return {
1340
+ content: [
1341
+ {
1342
+ type: "text",
1343
+ text: `Error: No match found for the search content. Closest candidate starts at line ${matchResult.candidateStartLine} (- = your searchContent, + = actual file content):\n\n${matchResult.candidateDiff}`,
1344
+ },
1345
+ ],
1346
+ };
1347
+ }
1294
1348
  return {
1295
1349
  content: [
1296
1350
  {
1297
1351
  type: "text",
1298
- text: `Error: Multiple matches found for the search content. Please provide a larger search block with unique surrounding context lines to make it unambiguous.`,
1352
+ text: `Error: Target search content not found in file, and no similar block was found to diff against.`,
1299
1353
  },
1300
1354
  ],
1301
1355
  };
1302
1356
  }
1303
- const updatedContent = originalContent.replace(searchContent, replaceContent);
1304
- fs.writeFileSync(resolved, updatedContent, "utf8");
1305
- return { content: [{ type: "text", text: `Success: Patch successfully applied to ${filePath}` }] };
1357
+ const match = matchResult[0];
1358
+ const contentLines = originalContent.split("\n");
1359
+ const finalReplace = match.strategy === "exact" ? replaceContent : reindentReplacement(replaceContent, searchContent, contentLines[match.startLine]);
1360
+ const updatedLines = [...contentLines.slice(0, match.startLine), ...finalReplace.split("\n"), ...contentLines.slice(match.endLine + 1)];
1361
+ fs.writeFileSync(resolved, updatedLines.join("\n"), "utf8");
1362
+ const note = match.strategy === "exact" ? "" : ` (matched via ${match.strategy}, score ${match.score.toFixed(2)})`;
1363
+ return { content: [{ type: "text", text: `Success: Patch successfully applied to ${filePath}${note}` }] };
1306
1364
  }
1307
1365
  catch (err) {
1308
1366
  logError("apply_workspace_patch", err);
@@ -1403,53 +1461,28 @@ async function handleListWorkspaceDir(args) {
1403
1461
  return { content: [{ type: "text", text: `Error listing directory: ${err.message}` }] };
1404
1462
  }
1405
1463
  }
1406
- function searchDirRecursive(currentDir, relativePath, query, extFilter) {
1407
- try {
1408
- const entries = fs.readdirSync(currentDir, { withFileTypes: true });
1409
- let result = [];
1410
- for (const entry of entries) {
1411
- if (["node_modules", ".git", "dist", "chroma_data", ".lemma"].includes(entry.name))
1412
- continue;
1413
- const rel = relativePath ? path.join(relativePath, entry.name) : entry.name;
1414
- const full = path.join(currentDir, entry.name);
1415
- if (entry.isDirectory()) {
1416
- result.push(...searchDirRecursive(full, rel, query, extFilter));
1417
- }
1418
- else {
1419
- if (extFilter && !entry.name.endsWith(`.${extFilter}`))
1420
- continue;
1421
- try {
1422
- const content = fs.readFileSync(full, "utf8");
1423
- if (content.toLowerCase().includes(query.toLowerCase())) {
1424
- const lines = content.split("\n");
1425
- lines.forEach((lineText, idx) => {
1426
- if (lineText.toLowerCase().includes(query.toLowerCase())) {
1427
- result.push({ filePath: rel, line: idx + 1, text: lineText.trim() });
1428
- }
1429
- });
1430
- }
1431
- }
1432
- catch { }
1433
- }
1434
- }
1435
- return result;
1436
- }
1437
- catch {
1438
- return [];
1439
- }
1440
- }
1441
1464
  async function handleSearchWorkspace(args) {
1442
1465
  const query = args?.query;
1443
1466
  const extension = args?.extension;
1467
+ const maxResults = args?.maxResults || 200;
1444
1468
  if (!query)
1445
1469
  throw new Error("query is required");
1446
1470
  const workspaceRoot = process.cwd();
1447
1471
  try {
1448
- const results = searchDirRecursive(workspaceRoot, "", query, extension);
1449
- if (results.length === 0) {
1450
- return { content: [{ type: "text", text: `No matches found in the workspace for "${query}".` }] };
1451
- }
1452
- let formatted = results.map((r) => `[${r.filePath}:${r.line}] ${r.text}`).join("\n");
1472
+ const extensions = parseExtensionFilter(extension);
1473
+ const cached = getCachedSearch(workspaceRoot, query, extensions, maxResults);
1474
+ if (cached.text !== null) {
1475
+ reportSavings({ source: "cache", tokens: Math.floor(cached.text.length / 4), toolName: "search_workspace", query: query.substring(0, 100) });
1476
+ return { content: [{ type: "text", text: cached.text }] };
1477
+ }
1478
+ const { matches, truncated } = searchWorkspace(workspaceRoot, query, extensions, maxResults);
1479
+ if (matches.length === 0) {
1480
+ const emptyText = `No matches found in the workspace for "${query}".`;
1481
+ setCachedSearch(query, extensions, maxResults, cached.fingerprint, emptyText);
1482
+ return { content: [{ type: "text", text: emptyText }] };
1483
+ }
1484
+ const grouped = groupSearchResults(matches, truncated, undefined, workspaceRoot);
1485
+ let formatted = grouped.formatted;
1453
1486
  try {
1454
1487
  const scrubber = new SemanticScrubber();
1455
1488
  const { maskedPrompt } = scrubber.mask(formatted);
@@ -1458,8 +1491,16 @@ async function handleSearchWorkspace(args) {
1458
1491
  catch (err) {
1459
1492
  logWarn("search_workspace", "SemanticScrubber failed, returning raw results");
1460
1493
  }
1494
+ const truncationNote = grouped.truncated ? ` (truncated at ${maxResults} matches — narrow your query or extension filter for the rest)` : "";
1495
+ const resultText = `Found ${grouped.totalMatches} matches across ${grouped.filesMatched} files${truncationNote}:\n\n${formatted}`;
1496
+ setCachedSearch(query, extensions, maxResults, cached.fingerprint, resultText);
1461
1497
  return {
1462
- content: [{ type: "text", text: `Found ${results.length} matches:\n\n${formatted}` }],
1498
+ content: [
1499
+ {
1500
+ type: "text",
1501
+ text: resultText,
1502
+ },
1503
+ ],
1463
1504
  };
1464
1505
  }
1465
1506
  catch (err) {