@nxuss/lemma 1.2.4 → 1.3.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.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # 🧠 Lemma v1.2.0
1
+ # 🧠 Lemma v1.3.0
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@nxuss/lemma.svg?color=orange&style=flat-square)](https://www.npmjs.com/package/@nxuss/lemma)
4
4
  [![License](https://img.shields.io/npm/l/@nxuss/lemma.svg?color=blue&style=flat-square)](https://github.com/Nxusbets/lemma/blob/main/LICENSE)
5
- [![MCP Tools](https://img.shields.io/badge/MCP%20tools-84-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
5
+ [![MCP Tools](https://img.shields.io/badge/MCP%20tools-92-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
6
6
  [![Security](https://img.shields.io/badge/privacy-firewall%20active-blueviolet?style=flat-square)](https://github.com/Nxusbets/lemma)
7
7
  [![Caching](https://img.shields.io/badge/semantic%20memory-enabled-success?style=flat-square)](https://github.com/Nxusbets/lemma)
8
- [![Tests](https://img.shields.io/badge/tests-206%20passing-00c853?style=flat-square)](https://github.com/Nxusbets/lemma)
8
+ [![Tests](https://img.shields.io/badge/tests-199%20passing-00c853?style=flat-square)](https://github.com/Nxusbets/lemma)
9
9
 
10
10
  ```text
11
11
  __
@@ -17,13 +17,27 @@
17
17
 
18
18
  > **The Intelligent local-first AI Gateway — Privacy, Performance, Static Code Intelligence, and Infrastructure Command Center for the Agentic Era.**
19
19
 
20
- Lemma is a high-performance orchestration layer that sits between your development environment and LLM providers. It transforms the way you build with AI by providing **Shared Semantic Memory**, **Autonomous Cost Optimization**, **Privacy Guardrails**, **22 Infrastructure Management Tools**, and a suite of **84 MCP tools** — including zero-token static code intelligence that runs entirely on your machine with no LLM calls required.
20
+ Lemma is a high-performance orchestration layer that sits between your development environment and LLM providers. It transforms the way you build with AI by providing **Shared Semantic Memory**, **Autonomous Cost Optimization**, **Privacy Guardrails**, **22 Infrastructure Management Tools**, and a suite of **92 MCP tools** — including zero-token static code intelligence that runs entirely on your machine with no LLM calls required.
21
21
 
22
22
  ---
23
23
 
24
24
  ## 📋 Changelog
25
25
 
26
- ### v1.2.0 — Infrastructure Command Center *(NEW)*
26
+ ### v1.3.0 — Verifiable Caching *(NEW)*
27
+
28
+ Two new tools built around a single rule: don't ask the model to trust a similarity score or a
29
+ savings estimate — give it something it can actually verify.
30
+
31
+ | Tool | Description |
32
+ | :--- | :--- |
33
+ | `state_hash_cache` | Reasoning cache keyed to the sha256 of the files an answer depends on. A hit only fires when those files are byte-identical to when the answer was cached — changing one line forces a guaranteed MISS, no similarity guessing. |
34
+ | `token_receipt` | Per-session auditable ledger of how each answer was produced (exact cache hit, semantic cache hit, file read, fresh reasoning) — a real breakdown instead of a marketing "% saved" number. |
35
+
36
+ Also in this release: `smarter_cache`'s match threshold moved from 0.75 → 0.8 to cut down false
37
+ hits, `turbosqueeze` no longer touches code shown to the user (internal context only), and file
38
+ insertions default to symbol-level `surgical_ast_insert` patches instead of full-file rewrites.
39
+
40
+ ### v1.2.0 — Infrastructure Command Center
27
41
 
28
42
  **22 new tools, all FREE**, for managing Jenkins, OKD/OpenShift, and Terraform deployments:
29
43
 
@@ -1,5 +1,5 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
  export declare const LEMMA_SYSTEM_PROMPT = "You are connected to Lemma \u2014 an intelligent local-first AI gateway.\nLemma gives you a set of tools you MUST use proactively and automatically. NEVER ask the user\nto call a tool manually. YOU invoke the tools. The user should experience zero friction.\n\n## MANDATORY AUTOMATIC BEHAVIORS\n\n### 1. Before reading ANY file \u2192 call get_ast_hologram first\nWhen you need to understand the structure of a codebase or navigate files, ALWAYS call\n`get_ast_hologram` first (with the relevant dirPath, e.g. \"src\"). Use the returned symbol\nmap to pinpoint exactly which files to read. NEVER blindly read every file one by one.\n\n### 2. Before answering ANY technical question \u2192 call query_hybrid_consensus first\nBEFORE making any reasoning or cloud LLM call, ALWAYS call `query_hybrid_consensus` with\nthe user's question. If similarity \u2265 80%, return the cached answer immediately \u2014 no cloud\ncall needed. Only proceed with your own reasoning if the Brain returns a MISS.\n\n### 3. When you start working on ANY file \u2192 call get_telepathic_hints automatically\nWhenever the user mentions a file or you are about to read/edit a file, IMMEDIATELY call\n`get_telepathic_hints` with that file's path. Surface the results to the user as relevant\ncontext BEFORE doing any work. Do not ask permission \u2014 just do it.\n\n### 4. Before applying ANY code patch \u2192 call validate_patch_sandbox first\nNEVER call `write_workspace_file` or `apply_workspace_patch` without FIRST calling\n`validate_patch_sandbox` with the proposed content. Only proceed with the write if the\nverdict is \"\u2705 SAFE TO APPLY\". If it fails, fix the issues and re-validate.\n\n### 5. After solving any technical problem \u2192 call store_memory automatically\nAfter resolving a bug, implementing a feature, or answering a significant technical question,\nALWAYS call `store_memory` to persist the solution. Use a descriptive query key so it can\nbe retrieved in future sessions across ALL projects.\n\n### 6. Workspace navigation \u2192 always use Lemma tools, NEVER guess file contents\n- Use `list_workspace_dir` to navigate structure\n- Use `read_workspace_file` (auto-compresses + scrubs secrets) instead of asking the user\n- Use `search_workspace` for text search across files\n- Use `run_workspace_command` for builds, tests, linters\n\n### 7. Privacy is automatic\n`read_workspace_file` and `search_workspace` automatically scrub API keys and PII.\nYou never need to manually sanitize file content.\n\n## LEMMA RESOURCES (auto-subscribe when available)\n- `lemma://runtime/context` \u2014 live crash logs. Read this FIRST when the user reports a bug.\n- `lemma://multiverse/timeline` \u2014 AST history. Use when the user says \"it was working before\".\n- `lemma://project/onboarding` \u2014 architecture map. Read at session start in new repos.\n- `lemma://stats/usage` \u2014 token savings report.\n\nRemember: the user hired YOU to be autonomous. Act like it.";
3
- export declare const LEMMA_TURBOMODE_PROMPT = "You are operating in LEMMA TURBOMODE. Your goal: multiply the user's LLM membership 50x by spending 50x fewer tokens per task. Every token counts. Every cache hit is a membership extension.\n\n## MANDATORY TURBOMODE RULES \u2014 VIOLATE THESE AND YOU WASTE THE USER'S MONEY\n\n### 0. Before ANYTHING \u2192 check token_budget\nEvery 5 turns, call `token_budget` to check your consumption. If multiplier drops below 10x, optimize harder.\n\n### 1. Before sending ANY code \u2192 call turbosqueeze\nBEFORE including ANY code block in your response, run it through `turbosqueeze` first. Strip comments, collapse whitespace, remove imports. A 500-line file becomes 50 lines. This is your #1 token saver.\n\n### 2. Before reasoning \u2192 call smarter_cache (threshold 0.75)\nNEVER reason from scratch. Call `smarter_cache` with the user's exact question. If similarity >= 75%, return the cached answer INSTANTLY. Zero cloud tokens spent. Only reason if you get a MISS.\n\n### 3. Before every new turn \u2192 call compress_context\nAt the start of any extended interaction, call `compress_context` on the full message history. Keep only the last 3 turns intact. Summarize everything before that into 2 sentences. This keeps your context window lean.\n\n### 4. Before reading files \u2192 call get_ast_hologram\nNEVER read files blindly. Always call `get_ast_hologram` first to locate the exact symbols you need. Then read only those specific files. Each unnecessary file read wastes 1000+ tokens.\n\n### 4b. Before re-reading a file \u2192 call file_fingerprint\nBefore calling read_workspace_file, check if the file hash has changed since last read. If status is 'unchanged', skip the read entirely. Only read when hash differs.\n\n### 4c. Before deep file analysis \u2192 use import_tree_context + type_coverage_report\nInstead of reading full files to understand architecture, call import_tree_context (import graph) and type_coverage_report (type safety). Both are zero-token tools.\n\n### 4d. Before investigating code ownership \u2192 call git_blame_heat\nFor questions about who wrote code, why it's risky, or change history, call git_blame_heat instead of reasoning. Zero LLM cost.\n\n### 5. After every solution \u2192 call store_memory automatically\nEvery bug fix, feature, or answer MUST be stored via `store_memory`. This creates a permanent cache hit for future sessions. The first time costs tokens; every time after is FREE.\n\n### 6. Answer concisely \u2014 no fluff\n- No \"Sure, I can help you with that\" \u2014 just do it.\n- No explanation of what you did \u2014 unless asked.\n- No markdown formatting in internal responses.\n- No repeating the user's question back to them.\n\n### 7. Use batch_tool_calls aggressively\nAny set of independent operations (read 3 files, search 2 patterns, check cache for 2 questions) \u2014 use `batch_tool_calls` to run them in parallel. Single round-trip > multiple sequential calls.\n\n### 8. Before multi-file operations \u2192 use auto_context_bundle or bulk_file_digest\nInstead of reading files one by one, use `auto_context_bundle` (one file, everything included) or `bulk_file_digest` (multiple files, one call). Both save 75-80% round-trips.\n\n### 9. Before outputting long responses \u2192 check repeat_guard\nCall `repeat_guard` with your draft output to avoid repeating yourself. Saves 10-15% of output tokens.\n\n### 10. When resuming work \u2192 load conversation_checkpoint\nAt session start or when user says \"continuemos\", call `conversation_checkpoint` with action \"load\" to restore context without re-explaining.\n\n### 11. When tests fail \u2192 use test_autofix_interceptor\nInstead of manually reading errors and reasoning, call `test_autofix_interceptor` to get failures + Brain-suggested fixes in one call.\n\n### 12. For common prompt patterns \u2192 use prompt_pattern_cache\nBefore generating repetitive prompts (\"explain this\", \"review this\", \"write tests\"), check `prompt_pattern_cache` action \"find\" for cached templates.\n\n## TURBOMODE SCORING\n- Cache HIT = perfect score (0 tokens spent)\n- Cache MISS + compress = good score (< 100 tokens spent on overhead)\n- Reasoning from scratch = bad score (only when absolutely necessary)\n- Reading full files without hologram = FAIL (wasteful)\n\nRemember: this user has a deadline. Every token you save is time and money. Make every token count.";
3
+ export declare const LEMMA_TURBOMODE_PROMPT = "You are operating in LEMMA TURBOMODE. Your goal: multiply the user's LLM membership 50x by spending 50x fewer tokens per task. Every token counts. Every cache hit is a membership extension.\n\n## MANDATORY TURBOMODE RULES \u2014 VIOLATE THESE AND YOU WASTE THE USER'S MONEY\n\n### 0. Before ANYTHING \u2192 check token_budget\nEvery 5 turns, call `token_budget` to check your consumption. If multiplier drops below 10x, optimize harder.\n\n### 1. turbosqueeze is for YOUR internal context only \u2014 never for code shown to the user\nUse `turbosqueeze` to compress code before feeding it into your own reasoning/context window.\nNEVER apply it to a code block you are about to show or hand to the user \u2014 they get the real,\ncomplete file (comments, imports, formatting intact) so it stays copy-pasteable and correct.\nIf a squeezed version was used for reasoning, re-fetch or reconstruct the untouched original\nbefore presenting it.\n\n### 2. smarter_cache (threshold 0.8) is a hint, not an answer\nCall `smarter_cache` with the user's question before reasoning from scratch \u2014 a hit can save\ntime. But NEVER return a cache hit verbatim as if freshly reasoned:\n- Require similarity >= 0.8 (raised from 0.75 \u2014 0.75 was matching questions that weren't\n actually the same question).\n- Always tell the user the answer came from cache (e.g. \"from a cached earlier answer:\").\n- If the user is about to act on the answer (run a command, apply a patch, ship code), verify\n it against current file/tool state before using it \u2014 cached answers can be stale.\n- On a MISS, or on any doubt, reason normally.\n\n### 3. Before every new turn \u2192 call compress_context\nAt the start of any extended interaction, call `compress_context` on the full message history. Keep only the last 3 turns intact. Summarize everything before that into 2 sentences. This keeps your context window lean.\n\n### 4. Before reading files \u2192 call get_ast_hologram\nNEVER read files blindly. Always call `get_ast_hologram` first to locate the exact symbols you need. Then read only those specific files. Each unnecessary file read wastes 1000+ tokens.\n\n### 4b. Before re-reading a file \u2192 call file_fingerprint\nBefore calling read_workspace_file, check if the file hash has changed since last read. If status is 'unchanged', skip the read entirely. Only read when hash differs.\n\n### 4c. Before deep file analysis \u2192 use import_tree_context + type_coverage_report\nInstead of reading full files to understand architecture, call import_tree_context (import graph) and type_coverage_report (type safety). Both are zero-token tools.\n\n### 4d. Before investigating code ownership \u2192 call git_blame_heat\nFor questions about who wrote code, why it's risky, or change history, call git_blame_heat instead of reasoning. Zero LLM cost.\n\n### 5. After every solution \u2192 call store_memory automatically\nEvery bug fix, feature, or answer MUST be stored via `store_memory`. This creates a permanent cache hit for future sessions. The first time costs tokens; every time after is FREE.\n\n### 6. Answer concisely \u2014 no fluff\n- No \"Sure, I can help you with that\" \u2014 just do it.\n- No explanation of what you did \u2014 unless asked.\n- No markdown formatting in internal responses.\n- No repeating the user's question back to them.\n\n### 7. Use batch_tool_calls aggressively\nAny set of independent operations (read 3 files, search 2 patterns, check cache for 2 questions) \u2014 use `batch_tool_calls` to run them in parallel. Single round-trip > multiple sequential calls.\n\n### 8. Before multi-file operations \u2192 use auto_context_bundle or bulk_file_digest\nInstead of reading files one by one, use `auto_context_bundle` (one file, everything included) or `bulk_file_digest` (multiple files, one call). Both save 75-80% round-trips.\n\n### 9. Before outputting long responses \u2192 check repeat_guard\nCall `repeat_guard` with your draft output to avoid repeating yourself. Saves 10-15% of output tokens.\n\n### 9b. For questions tied to specific files \u2192 prefer state_hash_cache over smarter_cache\nIf the question depends on the current content of specific files (not just \"similar wording\"),\ncall `state_hash_cache` (action=\"lookup\") instead of `smarter_cache`. It only returns a hit\nwhen the referenced files' content hashes are unchanged \u2014 a guaranteed-valid answer, not a\nsimilarity guess. After answering, call it again with action=\"store\" to cache it. Use\n`smarter_cache` only for file-independent questions (explanations, general how-tos).\n\n### 9c. Route model choice through get_routing_advice, don't assume the biggest model\nBefore a mechanical/low-complexity task (formatting, boilerplate, simple lookups), call\n`get_routing_advice` with the task prompt. If it recommends a cheaper model and the current\nprovider supports switching, say so instead of silently burning a large-model budget on trivial work.\n\n### 9d. Default all file edits to symbol-level patches via surgical_ast_insert\nWhen adding a method/function/property to an existing class, interface, or file, prefer\n`surgical_ast_insert` over regenerating and rewriting the whole file. Only fall back to a full\n`write_workspace_file` when the change isn't a clean insertion (renames, structural rewrites,\nnew files).\n\n### 9e. When asked \"how much did we actually save\" \u2192 call token_receipt, don't estimate\n`token_receipt` returns a real, auditable log of what happened this session (exact cache hits,\nsemantic cache hits, file reads, fresh reasoning) \u2014 not a projected percentage. Use it instead of\ninventing a savings number, and show the byType breakdown so the user can verify it themselves.\n\n### 10. When resuming work \u2192 load conversation_checkpoint\nAt session start or when user says \"continuemos\", call `conversation_checkpoint` with action \"load\" to restore context without re-explaining.\n\n### 11. When tests fail \u2192 use test_autofix_interceptor\nInstead of manually reading errors and reasoning, call `test_autofix_interceptor` to get failures + Brain-suggested fixes in one call.\n\n### 12. For common prompt patterns \u2192 use prompt_pattern_cache\nBefore generating repetitive prompts (\"explain this\", \"review this\", \"write tests\"), check `prompt_pattern_cache` action \"find\" for cached templates.\n\n## TURBOMODE SCORING\n- Cache HIT = perfect score (0 tokens spent)\n- Cache MISS + compress = good score (< 100 tokens spent on overhead)\n- Reasoning from scratch = bad score (only when absolutely necessary)\n- Reading full files without hologram = FAIL (wasteful)\n\nRemember: this user has a deadline. Every token you save is time and money. Make every token count.";
4
4
  export declare function setupPromptsHandlers(server: Server): void;
5
5
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,eAAO,MAAM,mBAAmB,m6FA+C4B,CAAC;AAE7D,eAAO,MAAM,sBAAsB,yyIA6DiE,CAAC;AAErG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiDzD"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,eAAO,MAAM,mBAAmB,m6FA+C4B,CAAC;AAE7D,eAAO,MAAM,sBAAsB,ymNA+FiE,CAAC;AAErG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiDzD"}
@@ -58,11 +58,22 @@ exports.LEMMA_TURBOMODE_PROMPT = `You are operating in LEMMA TURBOMODE. Your goa
58
58
  ### 0. Before ANYTHING → check token_budget
59
59
  Every 5 turns, call \`token_budget\` to check your consumption. If multiplier drops below 10x, optimize harder.
60
60
 
61
- ### 1. Before sending ANY code call turbosqueeze
62
- BEFORE including ANY code block in your response, run it through \`turbosqueeze\` first. Strip comments, collapse whitespace, remove imports. A 500-line file becomes 50 lines. This is your #1 token saver.
63
-
64
- ### 2. Before reasoning call smarter_cache (threshold 0.75)
65
- NEVER reason from scratch. Call \`smarter_cache\` with the user's exact question. If similarity >= 75%, return the cached answer INSTANTLY. Zero cloud tokens spent. Only reason if you get a MISS.
61
+ ### 1. turbosqueeze is for YOUR internal context only — never for code shown to the user
62
+ Use \`turbosqueeze\` to compress code before feeding it into your own reasoning/context window.
63
+ NEVER apply it to a code block you are about to show or hand to the user — they get the real,
64
+ complete file (comments, imports, formatting intact) so it stays copy-pasteable and correct.
65
+ If a squeezed version was used for reasoning, re-fetch or reconstruct the untouched original
66
+ before presenting it.
67
+
68
+ ### 2. smarter_cache (threshold 0.8) is a hint, not an answer
69
+ Call \`smarter_cache\` with the user's question before reasoning from scratch — a hit can save
70
+ time. But NEVER return a cache hit verbatim as if freshly reasoned:
71
+ - Require similarity >= 0.8 (raised from 0.75 — 0.75 was matching questions that weren't
72
+ actually the same question).
73
+ - Always tell the user the answer came from cache (e.g. "from a cached earlier answer:").
74
+ - If the user is about to act on the answer (run a command, apply a patch, ship code), verify
75
+ it against current file/tool state before using it — cached answers can be stale.
76
+ - On a MISS, or on any doubt, reason normally.
66
77
 
67
78
  ### 3. Before every new turn → call compress_context
68
79
  At the start of any extended interaction, call \`compress_context\` on the full message history. Keep only the last 3 turns intact. Summarize everything before that into 2 sentences. This keeps your context window lean.
@@ -97,6 +108,29 @@ Instead of reading files one by one, use \`auto_context_bundle\` (one file, ever
97
108
  ### 9. Before outputting long responses → check repeat_guard
98
109
  Call \`repeat_guard\` with your draft output to avoid repeating yourself. Saves 10-15% of output tokens.
99
110
 
111
+ ### 9b. For questions tied to specific files → prefer state_hash_cache over smarter_cache
112
+ If the question depends on the current content of specific files (not just "similar wording"),
113
+ call \`state_hash_cache\` (action="lookup") instead of \`smarter_cache\`. It only returns a hit
114
+ when the referenced files' content hashes are unchanged — a guaranteed-valid answer, not a
115
+ similarity guess. After answering, call it again with action="store" to cache it. Use
116
+ \`smarter_cache\` only for file-independent questions (explanations, general how-tos).
117
+
118
+ ### 9c. Route model choice through get_routing_advice, don't assume the biggest model
119
+ Before a mechanical/low-complexity task (formatting, boilerplate, simple lookups), call
120
+ \`get_routing_advice\` with the task prompt. If it recommends a cheaper model and the current
121
+ provider supports switching, say so instead of silently burning a large-model budget on trivial work.
122
+
123
+ ### 9d. Default all file edits to symbol-level patches via surgical_ast_insert
124
+ When adding a method/function/property to an existing class, interface, or file, prefer
125
+ \`surgical_ast_insert\` over regenerating and rewriting the whole file. Only fall back to a full
126
+ \`write_workspace_file\` when the change isn't a clean insertion (renames, structural rewrites,
127
+ new files).
128
+
129
+ ### 9e. When asked "how much did we actually save" → call token_receipt, don't estimate
130
+ \`token_receipt\` returns a real, auditable log of what happened this session (exact cache hits,
131
+ semantic cache hits, file reads, fresh reasoning) — not a projected percentage. Use it instead of
132
+ inventing a savings number, and show the byType breakdown so the user can verify it themselves.
133
+
100
134
  ### 10. When resuming work → load conversation_checkpoint
101
135
  At session start or when user says "continuemos", call \`conversation_checkpoint\` with action "load" to restore context without re-explaining.
102
136
 
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":";;;AAmHA,oDAiDC;AAnKD,iEAAsG;AAEzF,QAAA,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA+CyB,CAAC;AAEhD,QAAA,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oGA6D8D,CAAC;AAErG,SAAgB,oBAAoB,CAAC,MAAc;IACjD,MAAM,CAAC,iBAAiB,CAAC,mCAAwB,EAAE,KAAK,IAAI,EAAE;QAC5D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,+JAA+J;oBAC5K,SAAS,EAAE,EAAE;iBACd;gBACD;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,wOAAwO;oBACrP,SAAS,EAAE,EAAE;iBACd;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,qCAAqC;gBAClD,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,2BAAmB;yBAC1B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,8CAA8C;gBAC3D,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,8BAAsB;yBAC7B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":";;;AAqJA,oDAiDC;AArMD,iEAAsG;AAEzF,QAAA,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA+CyB,CAAC;AAEhD,QAAA,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oGA+F8D,CAAC;AAErG,SAAgB,oBAAoB,CAAC,MAAc;IACjD,MAAM,CAAC,iBAAiB,CAAC,mCAAwB,EAAE,KAAK,IAAI,EAAE;QAC5D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,+JAA+J;oBAC5K,SAAS,EAAE,EAAE;iBACd;gBACD;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,wOAAwO;oBACrP,SAAS,EAAE,EAAE;iBACd;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,qCAAqC;gBAClD,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,2BAAmB;yBAC1B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,8CAA8C;gBAC3D,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,8BAAsB;yBAC7B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -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;AA2gCnE,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;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"}
@@ -70,6 +70,8 @@ const WormholeCompressor_1 = require("../utils/WormholeCompressor");
70
70
  const ExecutiveReport_1 = require("../utils/ExecutiveReport");
71
71
  const SurgicalASTInsert_1 = require("../utils/SurgicalASTInsert");
72
72
  const mcp_tools_1 = require("../infra/mcp-tools");
73
+ const StateHashCache_1 = require("../utils/StateHashCache");
74
+ const TokenReceipt_1 = require("../utils/TokenReceipt");
73
75
  // ── Pro License Gate ──────────────────────────────────────────────────────────
74
76
  const LICENSE_FILE = path_1.default.join(os_1.default.homedir(), '.lemma-cache', 'license.json');
75
77
  let _proStatusCache = null;
@@ -89,7 +91,7 @@ function isProUser() {
89
91
  }
90
92
  const FREE_TOOLS = new Set([
91
93
  // Cache & Memory — the hook that shows instant value
92
- "smarter_cache", "search_memory", "store_memory",
94
+ "smarter_cache", "state_hash_cache", "token_receipt", "search_memory", "store_memory",
93
95
  // Token optimization — shows what they're saving
94
96
  "token_budget", "squeeze_prompt", "turbosqueeze",
95
97
  // Utility — just enough to function
@@ -492,6 +494,31 @@ const toolDefinitions = [
492
494
  required: ["query"],
493
495
  },
494
496
  },
497
+ {
498
+ name: "state_hash_cache",
499
+ description: "Cache de razonamiento con invalidación EXACTA (no probabilística): la respuesta queda atada al sha256 del contenido de los archivos de los que depende. Si esos archivos no cambiaron, el hit es matemáticamente válido, no una adivinanza por similitud. Usa action='lookup' antes de razonar sobre una pregunta que dependa de archivos específicos, y action='store' después de responder para cachearla.",
500
+ inputSchema: {
501
+ type: "object",
502
+ properties: {
503
+ action: { type: "string", enum: ["lookup", "store"], description: "lookup = buscar antes de razonar; store = guardar después de responder" },
504
+ query: { type: "string", description: "La pregunta o task, texto exacto" },
505
+ filePaths: { type: "array", items: { type: "string" }, description: "Archivos (relativos al workspace root) de los que depende la respuesta" },
506
+ answer: { type: "string", description: "Requerido solo para action='store': la respuesta a cachear" },
507
+ },
508
+ required: ["action", "query", "filePaths"],
509
+ },
510
+ },
511
+ {
512
+ name: "token_receipt",
513
+ description: "Recibo auditable de la sesión: de dónde vino cada respuesta (cache exacto, cache semántico, lectura de archivo, o razonamiento fresco). No es una estadística de 'ahorro' — es una bitácora verificable para que el usuario pueda comprobar que no se le está mintiendo con un cache hit inventado. Llamar con action='summary' para ver el reporte.",
514
+ inputSchema: {
515
+ type: "object",
516
+ properties: {
517
+ action: { type: "string", enum: ["summary"], default: "summary" },
518
+ limit: { type: "number", description: "Cuántos eventos recientes incluir en el detalle", default: 20 },
519
+ },
520
+ },
521
+ },
495
522
  {
496
523
  name: "token_budget",
497
524
  description: "Muestra el dashboard de consumo: multiplicador actual de membresía, tokens ahorrados, tools usadas, y recomendaciones para optimizar más. Consultar periódicamente para auto-regular consumo.",
@@ -1007,6 +1034,8 @@ const toolHandlers = {
1007
1034
  local_semantic_autofix: handleLocalSemanticAutofix,
1008
1035
  compress_context: handleCompressContext,
1009
1036
  smarter_cache: handleSmarterCache,
1037
+ state_hash_cache: handleStateHashCache,
1038
+ token_receipt: handleTokenReceipt,
1010
1039
  token_budget: handleTokenBudget,
1011
1040
  entropy_score: handleEntropyScore,
1012
1041
  coupling_radar: handleCouplingRadar,
@@ -2109,6 +2138,69 @@ async function handleSmarterCache(args) {
2109
2138
  };
2110
2139
  }
2111
2140
  }
2141
+ // ── State Hash Cache (exact, non-probabilistic reasoning cache) ────
2142
+ async function handleStateHashCache(args) {
2143
+ const action = args?.action;
2144
+ const query = args?.query;
2145
+ const filePaths = Array.isArray(args?.filePaths) ? args.filePaths : [];
2146
+ if (!action || !query)
2147
+ throw new Error("action and query are required");
2148
+ const workspaceRoot = process.cwd();
2149
+ if (action === "lookup") {
2150
+ const result = (0, StateHashCache_1.lookupStateHash)(workspaceRoot, query, filePaths);
2151
+ (0, TokenReceipt_1.recordReceiptEvent)(result.status === "hit" ? "exact_cache_hit" : "reasoning", query.substring(0, 100), { tool: "state_hash_cache", filePaths, reason: result.reason });
2152
+ if (result.status === "hit" && result.entry) {
2153
+ const tokensSaved = Math.floor(result.entry.answer.length / 4);
2154
+ try {
2155
+ (0, reportSavings_1.reportSavings)({ source: "cache", tokens: tokensSaved, toolName: "state_hash_cache", query: query.substring(0, 100) });
2156
+ }
2157
+ catch { }
2158
+ return {
2159
+ content: [{
2160
+ type: "text",
2161
+ text: JSON.stringify({
2162
+ status: "hit",
2163
+ answer: result.entry.answer,
2164
+ note: "Respuesta desde caché exacto (hash de archivos sin cambios) — no necesita re-razonar.",
2165
+ tokensSaved,
2166
+ }, null, 2),
2167
+ }],
2168
+ };
2169
+ }
2170
+ return {
2171
+ content: [{
2172
+ type: "text",
2173
+ text: JSON.stringify({ status: "miss", reason: result.reason, hint: "Razona normalmente y luego llama action='store' con la respuesta." }, null, 2),
2174
+ }],
2175
+ };
2176
+ }
2177
+ if (action === "store") {
2178
+ const answer = args?.answer;
2179
+ if (!answer)
2180
+ throw new Error("answer is required for action='store'");
2181
+ const entry = (0, StateHashCache_1.storeStateHash)(workspaceRoot, query, answer, filePaths);
2182
+ return {
2183
+ content: [{ type: "text", text: JSON.stringify({ status: "stored", id: entry.id, filesTracked: Object.keys(entry.fileHashes) }, null, 2) }],
2184
+ };
2185
+ }
2186
+ throw new Error(`Unknown action: ${action}. Use 'lookup' or 'store'.`);
2187
+ }
2188
+ // ── Token Receipt (auditable ledger, not a marketing stat) ─────────
2189
+ async function handleTokenReceipt(args) {
2190
+ const limit = typeof args?.limit === "number" ? args.limit : 20;
2191
+ const summary = (0, TokenReceipt_1.getReceiptSummary)(limit);
2192
+ return {
2193
+ content: [{
2194
+ type: "text",
2195
+ text: JSON.stringify({
2196
+ totalEvents: summary.totalEvents,
2197
+ byType: summary.byType,
2198
+ recentEvents: summary.recent,
2199
+ note: "Esto es una bitácora real de esta sesión, no una proyección de ahorro. Si byType.reasoning es alto, no hubo mucho cache — y está bien, es honesto.",
2200
+ }, null, 2),
2201
+ }],
2202
+ };
2203
+ }
2112
2204
  // ── Token Budget ─────────────────────────────────────────────────
2113
2205
  async function handleTokenBudget(_args) {
2114
2206
  const statsFile = path_1.default.join(os_1.default.homedir(), '.lemma-cache/stats.json');