@nxuss/lemma 1.36.0 โ†’ 1.38.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 (143) hide show
  1. package/README.md +88 -426
  2. package/bin/brain-ingest.js +22 -0
  3. package/bin/doctor.js +31 -4
  4. package/bin/init.js +92 -51
  5. package/dashboard/README.md +48 -19
  6. package/dashboard/dist/assets/index-CLXWgzTm.css +1 -0
  7. package/dashboard/dist/assets/index-CoMIMxyC.js +451 -0
  8. package/dashboard/dist/index.html +2 -2
  9. package/dist/cjs/api/dashboardRoutes.d.ts.map +1 -1
  10. package/dist/cjs/api/dashboardRoutes.js +7 -3
  11. package/dist/cjs/api/dashboardRoutes.js.map +1 -1
  12. package/dist/cjs/autopilot/Notifier.d.ts.map +1 -1
  13. package/dist/cjs/autopilot/Notifier.js +3 -0
  14. package/dist/cjs/autopilot/Notifier.js.map +1 -1
  15. package/dist/cjs/cli/hostHooks.d.ts +13 -1
  16. package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
  17. package/dist/cjs/cli/hostHooks.js +34 -4
  18. package/dist/cjs/cli/hostHooks.js.map +1 -1
  19. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  20. package/dist/cjs/cli/lemma-proxy.js +235 -107
  21. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  22. package/dist/cjs/mcp/index.js +42 -18
  23. package/dist/cjs/mcp/index.js.map +1 -1
  24. package/dist/cjs/mcp/prompts.d.ts +1 -1
  25. package/dist/cjs/mcp/prompts.d.ts.map +1 -1
  26. package/dist/cjs/mcp/prompts.js +2 -0
  27. package/dist/cjs/mcp/prompts.js.map +1 -1
  28. package/dist/cjs/mcp/resources.d.ts.map +1 -1
  29. package/dist/cjs/mcp/resources.js +23 -4
  30. package/dist/cjs/mcp/resources.js.map +1 -1
  31. package/dist/cjs/mcp/tools/memory.js +11 -11
  32. package/dist/cjs/mcp/tools/memory.js.map +1 -1
  33. package/dist/cjs/mcp/tools/misc.js +1 -1
  34. package/dist/cjs/mcp/tools/misc.js.map +1 -1
  35. package/dist/cjs/mcp/tools/review.js +1 -1
  36. package/dist/cjs/mcp/tools/review.js.map +1 -1
  37. package/dist/cjs/mcp/tools/workspace.d.ts.map +1 -1
  38. package/dist/cjs/mcp/tools/workspace.js +10 -7
  39. package/dist/cjs/mcp/tools/workspace.js.map +1 -1
  40. package/dist/cjs/mcp/tools.d.ts +16 -1
  41. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  42. package/dist/cjs/mcp/tools.js +63 -33
  43. package/dist/cjs/mcp/tools.js.map +1 -1
  44. package/dist/cjs/mcp/workspaceShared.d.ts.map +1 -1
  45. package/dist/cjs/mcp/workspaceShared.js +6 -9
  46. package/dist/cjs/mcp/workspaceShared.js.map +1 -1
  47. package/dist/cjs/proxy/ProjectRegistry.d.ts +24 -0
  48. package/dist/cjs/proxy/ProjectRegistry.d.ts.map +1 -1
  49. package/dist/cjs/proxy/ProjectRegistry.js +50 -3
  50. package/dist/cjs/proxy/ProjectRegistry.js.map +1 -1
  51. package/dist/cjs/subconscious/HostRecall.d.ts +10 -1
  52. package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -1
  53. package/dist/cjs/subconscious/HostRecall.js +68 -6
  54. package/dist/cjs/subconscious/HostRecall.js.map +1 -1
  55. package/dist/cjs/subconscious/recallDigest.d.ts +34 -0
  56. package/dist/cjs/subconscious/recallDigest.d.ts.map +1 -0
  57. package/dist/cjs/subconscious/recallDigest.js +82 -0
  58. package/dist/cjs/subconscious/recallDigest.js.map +1 -0
  59. package/dist/cjs/utils/ProjectIdentity.d.ts +8 -0
  60. package/dist/cjs/utils/ProjectIdentity.d.ts.map +1 -1
  61. package/dist/cjs/utils/ProjectIdentity.js +15 -0
  62. package/dist/cjs/utils/ProjectIdentity.js.map +1 -1
  63. package/dist/cjs/utils/SavingsLedger.d.ts +2 -0
  64. package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -1
  65. package/dist/cjs/utils/SavingsLedger.js +5 -5
  66. package/dist/cjs/utils/SavingsLedger.js.map +1 -1
  67. package/dist/cjs/utils/TokenReceipt.d.ts +2 -0
  68. package/dist/cjs/utils/TokenReceipt.d.ts.map +1 -1
  69. package/dist/cjs/utils/TokenReceipt.js +11 -1
  70. package/dist/cjs/utils/TokenReceipt.js.map +1 -1
  71. package/dist/cjs/utils/reportSavings.d.ts +7 -0
  72. package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
  73. package/dist/cjs/utils/reportSavings.js +14 -2
  74. package/dist/cjs/utils/reportSavings.js.map +1 -1
  75. package/dist/esm/api/dashboardRoutes.d.ts.map +1 -1
  76. package/dist/esm/api/dashboardRoutes.js +7 -3
  77. package/dist/esm/api/dashboardRoutes.js.map +1 -1
  78. package/dist/esm/autopilot/Notifier.d.ts.map +1 -1
  79. package/dist/esm/autopilot/Notifier.js +3 -0
  80. package/dist/esm/autopilot/Notifier.js.map +1 -1
  81. package/dist/esm/cli/hostHooks.d.ts +13 -1
  82. package/dist/esm/cli/hostHooks.d.ts.map +1 -1
  83. package/dist/esm/cli/hostHooks.js +32 -3
  84. package/dist/esm/cli/hostHooks.js.map +1 -1
  85. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  86. package/dist/esm/cli/lemma-proxy.js +236 -108
  87. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  88. package/dist/esm/mcp/index.js +42 -18
  89. package/dist/esm/mcp/index.js.map +1 -1
  90. package/dist/esm/mcp/prompts.d.ts +1 -1
  91. package/dist/esm/mcp/prompts.d.ts.map +1 -1
  92. package/dist/esm/mcp/prompts.js +2 -0
  93. package/dist/esm/mcp/prompts.js.map +1 -1
  94. package/dist/esm/mcp/resources.d.ts.map +1 -1
  95. package/dist/esm/mcp/resources.js +23 -4
  96. package/dist/esm/mcp/resources.js.map +1 -1
  97. package/dist/esm/mcp/tools/memory.js +11 -11
  98. package/dist/esm/mcp/tools/memory.js.map +1 -1
  99. package/dist/esm/mcp/tools/misc.js +1 -1
  100. package/dist/esm/mcp/tools/misc.js.map +1 -1
  101. package/dist/esm/mcp/tools/review.js +1 -1
  102. package/dist/esm/mcp/tools/review.js.map +1 -1
  103. package/dist/esm/mcp/tools/workspace.d.ts.map +1 -1
  104. package/dist/esm/mcp/tools/workspace.js +10 -7
  105. package/dist/esm/mcp/tools/workspace.js.map +1 -1
  106. package/dist/esm/mcp/tools.d.ts +16 -1
  107. package/dist/esm/mcp/tools.d.ts.map +1 -1
  108. package/dist/esm/mcp/tools.js +62 -34
  109. package/dist/esm/mcp/tools.js.map +1 -1
  110. package/dist/esm/mcp/workspaceShared.d.ts.map +1 -1
  111. package/dist/esm/mcp/workspaceShared.js +6 -9
  112. package/dist/esm/mcp/workspaceShared.js.map +1 -1
  113. package/dist/esm/proxy/ProjectRegistry.d.ts +24 -0
  114. package/dist/esm/proxy/ProjectRegistry.d.ts.map +1 -1
  115. package/dist/esm/proxy/ProjectRegistry.js +49 -2
  116. package/dist/esm/proxy/ProjectRegistry.js.map +1 -1
  117. package/dist/esm/subconscious/HostRecall.d.ts +10 -1
  118. package/dist/esm/subconscious/HostRecall.d.ts.map +1 -1
  119. package/dist/esm/subconscious/HostRecall.js +66 -5
  120. package/dist/esm/subconscious/HostRecall.js.map +1 -1
  121. package/dist/esm/subconscious/recallDigest.d.ts +34 -0
  122. package/dist/esm/subconscious/recallDigest.d.ts.map +1 -0
  123. package/dist/esm/subconscious/recallDigest.js +76 -0
  124. package/dist/esm/subconscious/recallDigest.js.map +1 -0
  125. package/dist/esm/utils/ProjectIdentity.d.ts +8 -0
  126. package/dist/esm/utils/ProjectIdentity.d.ts.map +1 -1
  127. package/dist/esm/utils/ProjectIdentity.js +14 -0
  128. package/dist/esm/utils/ProjectIdentity.js.map +1 -1
  129. package/dist/esm/utils/SavingsLedger.d.ts +2 -0
  130. package/dist/esm/utils/SavingsLedger.d.ts.map +1 -1
  131. package/dist/esm/utils/SavingsLedger.js +1 -1
  132. package/dist/esm/utils/SavingsLedger.js.map +1 -1
  133. package/dist/esm/utils/TokenReceipt.d.ts +2 -0
  134. package/dist/esm/utils/TokenReceipt.d.ts.map +1 -1
  135. package/dist/esm/utils/TokenReceipt.js +10 -1
  136. package/dist/esm/utils/TokenReceipt.js.map +1 -1
  137. package/dist/esm/utils/reportSavings.d.ts +7 -0
  138. package/dist/esm/utils/reportSavings.d.ts.map +1 -1
  139. package/dist/esm/utils/reportSavings.js +13 -2
  140. package/dist/esm/utils/reportSavings.js.map +1 -1
  141. package/package.json +10 -3
  142. package/dashboard/dist/assets/index-D6nem4OA.js +0 -461
  143. package/dashboard/dist/assets/index-DNz43ews.css +0 -1
package/README.md CHANGED
@@ -2,471 +2,133 @@
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-110-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
6
- [![Security](https://img.shields.io/badge/privacy-firewall%20active-blueviolet?style=flat-square)](https://github.com/Nxusbets/lemma)
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-1003%20passing-00c853?style=flat-square)](https://github.com/Nxusbets/lemma)
9
-
10
- ```text
11
- __
12
- / / ___ ____ ___ ____ ___ ____ _
13
- / / / _ \/ __ `__ \/ __ `__ \/ __ `/
14
- / /___/ __/ / / / / / / / / / / /_/ /
15
- /_____/\___/_/ /_/ /_/_/ /_/ /_/\__,_/
16
- ```
17
-
18
- > **The Intelligent local-first AI Gateway โ€” Privacy, Performance, Static Code Intelligence, and Infrastructure Command Center for the Agentic Era.**
5
+ [![MCP](https://img.shields.io/badge/MCP-111%20tools-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
6
+ [![Local-first](https://img.shields.io/badge/local--first-no%20cloud%20required-success?style=flat-square)](https://github.com/Nxusbets/lemma)
19
7
 
20
- Lemma sits between your development environment and LLM providers as an MCP server / local proxy.
21
- It cuts what actually enters the model's context โ€” repeated reads, unfiltered command output, tool
22
- schemas the project can't use โ€” while keeping every answer verifiable: a cache hit is disclosed as
23
- a cache hit, a compressed file is never what the user sees, and a savings number always traces back
24
- to an auditable ledger, never an estimate.
8
+ **A memory your AI agent can verify, and a context window that only holds what matters.**
25
9
 
26
- ## ๐Ÿš€ Quick start
10
+ Coding agents forget everything between sessions, re-read the same files, and dump whole test
11
+ logs into their context. Lemma is a local MCP server (plus an optional proxy) that gives them a
12
+ project memory checked against your actual code, trims what enters the context, and keeps the
13
+ receipts โ€” including what Lemma itself costs.
27
14
 
28
15
  ```bash
29
16
  npm install -g @nxuss/lemma
30
- lemma init # auto-configures MCP for your IDE (Muse, Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode)
31
- lemma start # gateway + dashboard on http://localhost:8081
17
+ lemma init # wires Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode, Muse
32
18
  ```
33
19
 
34
- > **Muse** โ€” no setup needed. This repo is already Muse-compatible zero-config: clone and open with `muse` โ€” the skill at `.agents/skills/lemma/SKILL.md` auto-loads and `lemma call` works via `bash`. See [MCP integration](#-mcp-integration).
35
- >
36
- > **๐Ÿ†• v1.22.0 โ€” Lemma auto-activates in every LLM client.** `npm i -g @nxuss/lemma` registers the skill in your **user** catalog (auto-loads in every `muse` session, any project) and `lemma init` wires each project for Muse, Claude Code, Cursor, Codex, Windsurf, Kiro and OpenCode. Health check: `lemma doctor`.
37
- >
38
- > **๐Ÿ†• v1.35.0 โ€” recall *before* the answer, and memories that notice when the world moved.** A
39
- > status question ("what's still pending?") touches no file, so no post-tool hook ever fired for it
40
- > and an agent answered from stale notes. `lemma init` now also installs a `UserPromptSubmit` hook
41
- > that names the memories bearing on the prompt (with age and freshness) and reminds the agent to
42
- > verify live git/CI state for status questions. `store_memory` takes `refs` โ€” a commit, or an MR /
43
- > issue with the state it asserts โ€” and `verify_memory` checks them (`git`, `gh`, `glab`; anything it
44
- > cannot read is `unverified`, never `fresh`). Also: `search_memory` shows each hit's age and lists
45
- > below-floor near-misses as orientation only, `get_memory` stops saying "tracks nothing" for
46
- > claim-tracked entries, `lemma-checkpoint` leaves a store draft the next prompt surfaces once, and a
47
- > stale MCP build is reported by the prompt hook. Re-run `lemma init` after updating.
48
- >
49
- > **๐Ÿ†• v1.34.0 โ€” Dashboard fixes.** The header shows the real running version (from `/health`), the debugger's pause/resume now works against the proxy, the Vite dev proxy points at the right port, and `npm run build` rebuilds the dashboard so the published UI is never stale.
50
- >
51
- > **๐Ÿ†• v1.33.0 โ€” C# (.NET) support, honestly labeled.** New per-project language detection
52
- > (`.csproj/.sln`, target frameworks, mixed repos) and a read-only `capability_matrix` tool so clients
53
- > stop guessing what works outside TypeScript. `get_ast_hologram` and `get_symbol_surgical_context` now
54
- > serve C# (zero-dependency parser), `depgraph` gives using-based graphs with explicit `unresolved`
55
- > externals, and `validate_patch_sandbox` runs `dotnet build` on a temp project copy โ€” or says `NOT a
56
- > build` when there's no SDK. `refactor`, `surgical_ast_insert`, `type_coverage_report`, `entropy_score`
57
- > and `affected_tests` return `support level: fallback` on C# targets instead of faking it: nothing is
58
- > modified. No new runtime dependencies. See the [changelog](CHANGELOG.md).
59
- >
60
- > **๐Ÿ†• v1.32.0 โ€” what a command can see and reach.** `run_workspace_command` no longer hands the
61
- > child the host's whole environment (tokens, API keys, the license key): it gets a short allowlist,
62
- > extendable via `mcp.commandEnv.allow`. `cat`, `ls`, `grep`, `find`, `sed`โ€ฆ must keep their paths
63
- > inside the workspace, and on Windows a backslash executable path no longer passes as a bare name.
64
- > New and opt-in: `mcp.sandbox.mode: "docker"` runs each command in a throwaway container with only
65
- > the workspace, no network, no host environment and a read-only root, and fails closed if Docker is
66
- > unavailable. **Behavior change:** a command that relied on an inherited variable now needs it allowed
67
- > by name (or `mcp.commandEnv.mode: "inherit"`). Also fixed: options a tool advertised and ignored
68
- > (`generate_pr_workflow.autoApprove`, `jenkins_generate_pipeline`, `TaskLifecycle.cleanup`), now guarded
69
- > by a test. See the [changelog](CHANGELOG.md).
70
- >
71
- > **๐Ÿ†• v1.31.1 โ€” secrets, symlinks and stale fixes.** A second round of dogfooding (rounds 11-20)
72
- > found that `run_workspace_command` handed `.env` secrets to the model in clear (`cat .env`,
73
- > `grep -r PASSWORD .`) while `read_workspace_file` masked them โ€” command output is now scrubbed too.
74
- > Also closed: writes escaping the workspace through a dangling symlink, an allowlist that accepted
75
- > `./git` and `env sh -c`, a compressor that cut code at `//` inside strings, a scrubber that masked
76
- > code as secrets, `brain_trash purge` wiping the whole trash on an invalid `olderThanDays`, and
77
- > `local_semantic_autofix` presenting a stale fix as a clean zero-token hit (it now says `STALE`, or
78
- > that the fix is not anchored to any file). Patches keep your CRLF line endings and tab/space
79
- > indentation, and `list_workspace_dir` caps huge directories. See the [changelog](CHANGELOG.md).
80
- >
81
- > **๐Ÿ†• v1.31.0 โ€” tools that said "success" without doing the job, fixed.** Dogfooding with a small
82
- > project driven only through Lemma's own tools found a pattern: several tools answered cleanly
83
- > without having done what was asked. `validate_patch_sandbox` approved *every* patch (it ran `npx tsc`
84
- > in an empty temp dir, which resolves a different package); `surgical_ast_insert` ignored an unknown
85
- > parameter, appended code outside the class and reported success (it now refuses syntax-breaking
86
- > patches); `get_ast_hologram` ignored `filePath` and scanned the whole repo (212K chars);
87
- > `search_workspace` could not find its own source file (two stray NUL bytes made it look binary).
88
- > Also fixed: `type_coverage_report` counting inferred types as missing, `affected_tests` using the root
89
- > runner for nested packages, lockfiles and changelogs ranking as "risk 100" in `git_heatmap_risk` /
90
- > `precrime_static`, `review_diff` flagging missing tests that already exist, and `brain_export`
91
- > being annotated read-only while it writes a file.
92
- > New: every result now says when an **argument was ignored** (`โš ๏ธ Lemma ignored unknown argument โ€ฆ
93
- > Valid: โ€ฆ`, also on failures), and when a **newer build exists than the running MCP process** โ€” a
94
- > rebuild never reaches a process that is already running, so reconnect it (Claude Code: `/mcp` โ†’
95
- > lemma). `get_symbol_surgical_context` now resolves methods (`Class.method`).
96
- > **Behavior change:** the extra "Proceed?" confirmation on `run_workspace_command`,
97
- > `apply_workspace_patch` and `forget_memory` is now **off by default** (the allowlist and path checks
98
- > are unchanged); set `"mcp": { "confirmActions": true }` in `lemma.config.json` to get it back.
99
- >
100
- > **๐Ÿ†• v1.30.1 โ€” `lemma init` now really installs the Brain's hooks, and big search results stop eating
101
- > your context.** Dogfooding found that `lemma init` finished "successfully" without installing the
102
- > git hooks (`post-commit`, `post-merge`, `post-checkout`) or the Claude Code / Codex / Cursor /
103
- > OpenCode tool hooks that v1.28โ€“v1.30 advertised โ€” so commits never became memories. Fixed
104
- > (idempotent, merge-only, `--no-hooks` to skip); re-run `lemma init` after updating.
105
- > `search_workspace` also had a match cap but no size cap: one hit inside a minified bundle returned
106
- > the whole line (~75k tokens reproduced). Lines are now a 240-char window around the hit and the
107
- > result is capped at ~8k tokens, with what was dropped disclosed. Plus 10% smaller tool schemas
108
- > (โˆ’938 tokens per session).
109
- >
110
- > **๐Ÿ†• v1.30.0 โ€” the Brain speaks through your agent's own tools, for zero tokens.** Agents read,
111
- > edit and test with their native tools, so the Brain used to stay silent unless the model
112
- > remembered `search_memory`. Now a post-tool hook answers at the three moments a memory is worth
113
- > the most: reading a file the Brain has notes on (their ids), editing code where an approach
114
- > already **failed**, and a test/build/lint failing with an error the Brain has a recorded **fix**
115
- > for. Local BM25 + hashes, no model tokens; ids and one line only (~35 tokens), and silent by
116
- > default โ€” no match, a stale fix, or a note already given this session says nothing. `lemma init`
117
- > wires it for **Claude Code, Codex, Cursor and OpenCode**. Also fixes `store()`'s dedup leaking
118
- > across projects (the same fix in a second repo was dropped as a "duplicate").
119
- >
120
- > **๐Ÿ†• v1.29.0 โ€” the dashboard shows what the Brain knows.** `lemma start` now opens with a
121
- > ๐Ÿง  Brain panel: how many files of your codebase it carries evidence about, how many times a
122
- > memory reached an agent's context, growth this week, how much of it is verifiable against the
123
- > code, where memories come from (manual, red โ†’ green fixes, tests, commits, team), and the most
124
- > recalled ones. Token savings stay as a footnote โ€” the Brain's value is agents not re-discovering
125
- > context. Same numbers in `brain_stats` and at `GET /api/brain/stats`.
126
- >
127
- > **๐Ÿ†• v1.28.0 โ€” the Brain goes team-wide through git, and fills itself.** `brain_team push`
128
- > writes your verified memories into the repo (`.lemma-brain/memories/`, one reviewable JSON file
129
- > each, paths relative to the repo root); `brain_team pull` โ€” automatic on merge/checkout once
130
- > `lemma init` installs the hooks โ€” imports a teammate's memories rebased onto *your* checkout. A
131
- > memory about a file that is byte-identical on your machine arrives **fresh**; one whose file has
132
- > moved on arrives **stale**, never silently trusted. And memories no longer depend on the model
133
- > remembering `store_memory`: a test/build/lint command that goes **red โ†’ green** is captured as
134
- > `fix: <the error>` + the files and diff that fixed it โ€” searchable by the exact error message next
135
- > time โ€” whether it ran through `run_workspace_command` or the agent's own shell (Claude Code
136
- > `PostToolUse` hook). Commits become memories anchored to their own blobs. Also fixes
137
- > `lemma-brain-ingest` silently dropping everything it ingested.
138
- >
139
- > **๐Ÿ†• v1.26.0 โ€” a memory without evidence is no longer sold as a verified hit, and the Brain
140
- > repairs it on the spot.** `search_memory` now splits its results into three buckets โ€” `fresh`
141
- > (tracked + verified, the only ones credited `tokensSaved`/`hits`), `stale`, and `UNTRACKED`
142
- > (no files/symbols to re-check: flagged with โš ๏ธ and its remedy, never "from cache"). On the
143
- > maintenance side, `brain_upkeep` auto-anchors those evidence-free memories when their body
144
- > names real repo files โ€” corpus snapshot first (`auto-anchor`), reversible via
145
- > `brain_trash restore-snapshot`; `autoAnchor:false` keeps the old read-only pass.
146
- >
147
- > **๐Ÿ†• v1.24.0 โ€” the Brain stops crediting what it can't verify.** `smarter_cache` no longer
148
- > presents a stale hit as a clean one (`stale:true`/`tokensSaved:0` + why, instead of a silent
149
- > guess); `store_memory` derives evidence by default from files/symbols the session already
150
- > touched instead of depending on the caller to pass them; every "tokens saved" figure now cites
151
- > the `hits` that earned it. See [`CHANGELOG.md`](CHANGELOG.md) for the full list.
20
+ That's it: your agent now has Lemma's tools. The dashboard opens at `http://localhost:8081/dashboard/`.
152
21
 
153
22
  ---
154
23
 
155
- ## โœจ What Lemma actually does
156
-
157
- - **Shared Semantic Memory ("The Brain")** โ€” a zero-dependency local index (BM25 + Jaccard, no
158
- ChromaDB/Ollama required) that persists solutions, fixes, and decisions across every project and
159
- every session, with claim- and symbol-level freshness so a stale answer can't hide behind a fresh
160
- one. Memories can depend on other memories (`derivedFrom`) and inherit their staleness
161
- transitively; `verify_memory` batch-revalidates a set of ids by hash-compare alone, no search
162
- round trip; `semanticDiff` tells a comment/formatting-only edit apart from a real one so
163
- reformatting a file doesn't falsely invalidate what was learned about it. Write tools
164
- (`surgical_ast_insert`, `apply_workspace_patch`, `write_workspace_file`) warn proactively when
165
- the code they're about to touch has dependent memories โ€” including a documented failed
166
- attempt โ€” instead of only finding out on the next search. Ranking factors in
167
- real usage (`hits`), explicit negative feedback (`downvote_memory`), and `cognitive_map` domain
168
- tags; a command that goes red โ†’ green auto-captures the fix (see below); two memories
169
- about the same symbol that disagree on outcome are flagged, not silently both suggested.
170
- Every hit explains itself (`whyShown` ranking signals + cited `evidence` files/symbols), and
171
- every reuse books its savings onto the memory itself โ€” `brain_stats` and `brain_upkeep` name
172
- which memories actually pay for the Brain (`totalTokensSaved` alongside the `hits` that earned
173
- it, never one without the other). `store_memory` derives `filePaths`/`symbols` by default from
174
- whatever the session already read, wrote, or patched when the caller doesn't pass them โ€”
175
- flagged as auto-derived in the response, correctable, but no longer opt-in.
176
- - **A Brain that speaks up on its own, through the host's tools** โ€” a post-tool hook
177
- (`lemma-brain-ingest --hook-result --host=claude|codex|cursor|opencode`) points at memories when
178
- the agent reads a file they're about to matter for, warns when an edit touches a documented
179
- failed attempt, and names the recorded fix when a verdict command fails with an error already
180
- fixed in *this* project (term overlap between error headlines decides "the same failure", not
181
- BM25 rank). No model tokens to compute, ids instead of bodies, deduped per host session, and a
182
- pointer never counts as reuse. Codex's shell reads (`cat`, `sed -n`, โ€ฆ) and `apply_patch` edits
183
- are recovered from the command; OpenCode gets a plugin, since it has no hook protocol.
184
- Windsurf/Devin post-hooks can't inject context, and Kiro's hooks spend tokens by design, so
185
- neither is wired.
186
- - **Recall before the agent answers, and memories that know when the world moved** โ€” a
187
- `UserPromptSubmit` hook (`lemma-brain-ingest --prompt-submit`, Claude Code) points at the
188
- memories a prompt substantially covers and, for status-style questions, says to verify live state
189
- first: file-hash freshness can't see an MR merge. `store_memory` / `update_memory` accept
190
- `refs` (`{kind:'commit',sha}`, or `{kind:'mr'|'issue',provider,id,state}`), and `verify_memory`
191
- checks them with `git` / `gh` / `glab` โ€” stale when they moved, `unverified` (never `fresh`) when
192
- they can't be read. The session-end checkpoint leaves a one-shot reminder to store what was
193
- verified.
194
- - **A team Brain, shared through git** โ€” `brain_team push` writes this project's fresh, tracked
195
- memories to `.lemma-brain/memories/<id>.json`: one sorted-key JSON file per memory, so two people
196
- sharing at once never conflict, every shared memory goes through code review, and deleting one is
197
- a `git rm`. Evidence is stored relative to the repo root and rebased onto each clone on `pull`,
198
- hashes untouched โ€” a teammate's memory is verified against *your* files, fresh only if they are
199
- byte-identical. Never shared: conversation checkpoints, commit memories (each clone derives its
200
- own), untracked or stale memories, evidence outside the repo, or anything derived from a memory
201
- that isn't shared. A pulled path that is absolute or escapes the repo is rejected; a memory a
202
- teammate deletes leaves your clone into `brain_trash` (restorable), and one you wrote yourself is
203
- never removed. Pushing is always explicit; pulling is a no-op when nothing changed, so it runs on
204
- every merge/checkout. `brain_team status` shows both sides; `dryRun:true` previews either.
205
- - **Memories that write themselves** โ€” a verdict command (jest, vitest, pytest, tsc, eslint, `go
206
- test`, `cargo test`, `npm test`/`build`/`lint`, โ€ฆ) that fails and later passes stores
207
- `fix: <headline error>` with the failure signature, the files whose content changed between the
208
- two runs, and their diff โ€” tracked against those files, tagged `confirmed`, source `auto-fix`.
209
- A pass with nothing changed since the failure is treated as flaky and stores nothing; a "fix" over
210
- 15 files is a refactor and stores nothing. It sees `run_workspace_command`, `test_oracle`, and โ€” via
211
- `lemma-brain-ingest --hook-result` โ€” the agent's own Bash tool. Commits are ingested with each
212
- touched file anchored to its blob *in that commit* (`git show sha:path`), not to the working copy.
213
- `lemma init` installs the `post-commit`, `post-merge` and `post-checkout` hooks that drive this
214
- (appended to existing hooks, idempotent, never touches a versioned `core.hooksPath` like husky).
215
- - **A memory that maintains itself** โ€” `brain_upkeep` revalidates the most-reused memories,
216
- surfaces exact duplicates and merge candidates, dead weight, and savings, each finding with its
217
- fix. Since v1.26.0 it also **auto-anchors** evidence-free memories whose body names real repo
218
- files โ€” snapshot first (`auto-anchor`), then re-anchored to those paths so they become
219
- verifiable; `autoAnchor:false` keeps the pass read-only, and everything is reversible via
220
- `brain_trash restore-snapshot`. `brain_merge` folds near-duplicate fragments into one
221
- canonical entry (fragments survive as evidence-carrying claims). `forget_memory` moves to a
222
- trash (`brain_trash`: list/restore/purge) instead of destroying, automatic snapshots roll
223
- back every forget/import/clear/merge, and `brain_import dryRun:true` previews a bundle โ€”
224
- counts plus opposite-outcome conflicts โ€” before a byte is written. Session onboarding
225
- re-checks freshness of the memories it lists, so a day-one answer never starts stale.
226
- - **Integrity and encryption at rest** โ€” the corpus carries a sha256 sidecar with `.prev`
227
- backup rotation: a half-written or rotted file serves its intact lines, falls back to the
228
- backup on total loss, and quarantines (never deletes) the bad bytes, with the incident
229
- surfaced in `brain_stats`. `LEMMA_BRAIN_ENCRYPT=1` (or `LEMMA_BRAIN_KEY`) stores the
230
- corpus AES-256-GCM encrypted under a local 0600 key; secrets never reach disk at all โ€”
231
- scrub-on-store redacts credentials one-way before indexing or persisting.
232
- - **Verifiable caching, not marketing numbers** โ€” `state_hash_cache` only hits when the files an
233
- answer depends on are byte-identical, and reading a file it already tracks an answer for
234
- surfaces that proactively, the same way a Brain memory does. A `smarter_cache` hit on a memory
235
- whose evidence changed comes back `stale:true`/`tokensSaved:0` with a warning instead of
236
- looking like a clean hit. `token_receipt` gives a real per-session breakdown of how each answer
237
- was produced instead of an invented "% saved."
238
- - **Privacy Firewall** โ€” API keys, credentials, and PII are scrubbed automatically from every file
239
- read and workspace search, before anything leaves your machine.
240
- - **Zero-token static intelligence** โ€” dependency graphs, entropy/coupling/risk scores, and an AST
241
- symbol index, computed locally with the TypeScript Compiler API. No LLM calls, no tokens.
242
- C# projects get the same treatment where it's real: symbol holograms and surgical context via a
243
- zero-dependency parser, using-based dependency graphs, and `dotnet build` patch validation โ€”
244
- everything else reports `fallback` instead of pretending (see `capability_matrix`).
245
- - **Command output distillation** โ€” a failing `npm test`/`tsc` run is parsed by deterministic
246
- per-format rules (jest, tsc, eslint) down to the failures that matter; the full output is never
247
- lost, just stored and retrievable on demand.
248
- - **Surgical, AST-based patching** โ€” `surgical_ast_insert` and `refactor` edit or rename by
249
- compiler-verified AST location instead of asking the model to output a full-file rewrite.
250
- - **Infrastructure Command Center** โ€” 22 free tools for Jenkins, OKD/OpenShift, and Terraform:
251
- discover, connect, deploy, diagnose, and detect drift, all via MCP.
252
- - **Scoped tool surface** โ€” of the 111 registered tools, only the ones your project shows evidence
253
- of needing are advertised to the model each turn; the rest stay one `lemma_toolbox` call away.
254
-
255
- See [`CHANGELOG.md`](CHANGELOG.md) for the full, per-version history.
24
+ ## Why Lemma
256
25
 
257
- ---
26
+ **๐Ÿง  A memory that knows when it's out of date.** The Brain stores fixes, decisions and context
27
+ in a local index (BM25, no embeddings service, no cloud). Every memory is tied to the files and
28
+ symbols it's about, so when the code changes it comes back **stale** instead of confidently
29
+ wrong โ€” and a memory with no evidence is labelled as such, never sold as a verified answer.
258
30
 
259
- ## ๐Ÿ’Ž Free vs Pro
31
+ **โœ๏ธ It fills itself.** A test, build or lint command that goes red โ†’ green is saved as
32
+ `fix: <the error>` with the diff that fixed it. Commits become memories. Next time the same
33
+ error shows up, the agent is pointed at the fix โ€” through hooks in Claude Code, Codex, Cursor
34
+ and OpenCode, for zero model tokens.
260
35
 
261
- 61 of the 111 registered tools work with no license; 50 require Pro. Enforced by one allowlist in
262
- code (`FREE_TOOLS` in `src/mcp/tools.ts`, including all 22 infrastructure tools), not by narrative.
263
- A session without a license doesn't even advertise the Pro tools โ€” they stay registered and
264
- discoverable via `lemma_toolbox`.
36
+ **๐Ÿ‘ฅ Shared through git.** `brain_team push` writes verified memories into the repo, one
37
+ reviewable JSON file each. Teammates pull them on merge/checkout, re-verified against *their*
38
+ checkout.
265
39
 
266
- | | Free (60) | Pro (50) |
267
- | :--- | :--- | :--- |
268
- | **Caching & memory** | `smarter_cache`, `state_hash_cache`, `token_receipt`, `search_memory`, `list_memories`, `store_memory`, `downvote_memory`, `verify_memory`, `token_budget`, `brain_upkeep`, `brain_trash`, `brain_merge`, `brain_team` | `get_telepathic_hints`, `query_hybrid_consensus`, `semantic_dedup_guard`, `local_semantic_autofix` |
269
- | **Reading & context** | `read_workspace_file`, `scrub_privacy`, `import_tree_context`, `bulk_file_digest`, `auto_context_bundle`, `git_blame_heat`, `type_coverage_report` | `get_ast_hologram`, `smart_file_slice`, `get_symbol_surgical_context`, `diff_only` |
270
- | **Writing & workspace** | โ€” | `write_workspace_file`, `apply_workspace_patch`, `multi_file_patch`, `search_workspace`, `run_workspace_command`, `validate_patch_sandbox`, `surgical_ast_insert` |
271
- | **Static analysis** | โ€” | `entropy_score`, `coupling_radar`, `pattern_fossil`, `precrime_static`, `dead_export_necromancer`, `depgraph`, `refactor`, `ast_flow_visualizer`, `cognitive_map` |
272
- | **Infrastructure** | All 22: `infra_*`, `jenkins_*`, `okd_*`, `terraform_*` | โ€” |
273
- | **Automation & PR review** | `conversation_checkpoint`, `test_autofix_interceptor`, `prompt_pattern_cache` | `review_diff`, `review_pr`, `pr_status`, `test_oracle`, `auto_heal`, AutoPilot, Silent Patch Watcher |
40
+ **โœ‚๏ธ Less noise in the context.** Large search results are capped, failing test/`tsc`/lint
41
+ output is distilled to the failures that matter (the full log stays retrievable), and a command
42
+ that prints the same thing twice comes back as `IDENTICAL` or a diff. Only the tools your
43
+ project needs are advertised; the rest are one `lemma_toolbox` call away.
274
44
 
275
- Get Pro: `lemma activate <key>` โ†’ [lemma.nxus.studio/upgrade](https://lemma.nxus.studio/upgrade)
45
+ **๐Ÿ”’ Private by default.** API keys, credentials and PII are masked in file reads, searches and
46
+ command output before they reach the model. Commands run with a minimal environment and
47
+ workspace-bound paths, or in an opt-in Docker sandbox. Everything binds to `127.0.0.1`.
276
48
 
277
- Full per-tool listing: `lemma_toolbox { "action": "list" }`.
49
+ **๐Ÿ“Š Numbers you can check.** Lemma records what it saves **and what it spends** โ€” its own
50
+ prompt, tool schemas and every result it adds to the context โ€” and the dashboard shows the net
51
+ balance next to the gross. A cache hit says it's a cache hit; `token_receipt` shows how each
52
+ answer was produced.
53
+
54
+ **๐Ÿงฐ Static intelligence without tokens.** Dependency graphs, coupling/risk scores and AST
55
+ symbol lookups computed locally with the TypeScript compiler, plus surgical AST edits instead of
56
+ full-file rewrites. C# gets the parts that are real; the rest says `fallback` instead of
57
+ pretending (`capability_matrix`).
278
58
 
279
59
  ---
280
60
 
281
- ## ๐ŸŽš๏ธ Tool profiles
61
+ ## Free vs Pro
282
62
 
283
- Every advertised tool schema is re-sent on **every request** of the session โ€” advertising all 110
284
- costs ~11,900 tokens/turn. Lemma advertises a scoped surface instead: core tools always, situational
285
- groups (e.g. infrastructure) only when the repo shows evidence for them. Nothing is removed โ€”
286
- everything stays registered and reachable via `lemma_toolbox`.
63
+ 61 of the 111 tools are free, including all memory, upkeep and export tools and the 22
64
+ infrastructure tools (Jenkins, OKD/OpenShift, Terraform). Pro adds writing and patching,
65
+ `search_workspace`, `run_workspace_command`, static analysis, PR review and auto-heal.
287
66
 
288
- ```jsonc
289
- // lemma.config.json
290
- { "mcp": { "toolProfile": "full" } } // "auto" (default) | "core" | "full"
291
- ```
292
-
293
- ```jsonc
294
- lemma_toolbox { "action": "list", "query": "terraform drift" } // what exists
295
- lemma_toolbox { "action": "schema", "tool": "terraform_drift" } // its inputs
296
- lemma_toolbox { "action": "call", "tool": "terraform_drift", "args": {} }
297
- ```
67
+ | | Free | Pro |
68
+ | :--- | :--- | :--- |
69
+ | Memory | `search_memory`, `store_memory`, `get_memory`, `update_memory`, `verify_memory`, `brain_team`, `brain_upkeep`, `brain_export`โ€ฆ | `get_telepathic_hints`, `semantic_dedup_guard`, `local_semantic_autofix` |
70
+ | Context | `read_workspace_file`, `scrub_privacy`, `token_budget`, `token_receipt`, `auto_context_bundle` | `get_ast_hologram`, `smart_file_slice`, `get_symbol_surgical_context` |
71
+ | Workspace | โ€” | `apply_workspace_patch`, `write_workspace_file`, `run_workspace_command`, `validate_patch_sandbox`, `surgical_ast_insert` |
72
+ | Analysis & review | `type_coverage_report`, `git_blame_heat` | `depgraph`, `entropy_score`, `refactor`, `review_diff`, `review_pr`, `test_oracle` |
73
+ | Infrastructure | all 22 `infra_*`, `jenkins_*`, `okd_*`, `terraform_*` | โ€” |
298
74
 
299
- `token_budget` reports the profile in use and what the advertised schemas actually cost this session.
75
+ Without a license, Pro tools aren't advertised to the model at all. Full list:
76
+ `lemma_toolbox { "action": "list" }`. Get Pro: `lemma activate <key>` โ†’
77
+ [lemma.nxus.studio/upgrade](https://lemma.nxus.studio/upgrade).
300
78
 
301
79
  ---
302
80
 
303
- ## ๐Ÿ› ๏ธ CLI reference
81
+ ## Setup
304
82
 
305
- | Command | Action |
83
+ | Client | How |
306
84
  | :--- | :--- |
307
- | `lemma init` | Bootstraps config, auto-configures MCP for OpenCode, Claude Desktop, Cursor, Windsurf, Kiro, VS Code, and installs the hooks that feed the Brain: git hooks, plus the tool hooks for Claude Code, Codex, Cursor and OpenCode (`--no-hooks` to skip). |
308
- | `lemma start` | Launches proxy, cache engine, and dashboard at `http://localhost:8081` (gateway savings + Brain knowledge panel). |
309
- | `lemma stop` / `lemma status` / `lemma stats` | Stop, health check, and net token/cost report (reports `NET COST` when a session is underwater). |
310
- | `lemma mcp` | Starts the stdin/stdout MCP server for IDE integration. |
311
- | `lemma heal` / `lemma autopilot` / `lemma watch` | Diagnose+repair the last crash / toggle autonomous fix-apply / silent patch-only watcher. |
312
- | `lemma patches` / `lemma apply <id>` / `lemma discard <id>` | List, apply, or discard a pending Silent Patch Watcher fix. |
313
- | `lemma activate <key>` | Activate a Pro license. |
314
- | `lemma-checkpoint [projectRoot]` | Derive a session checkpoint from repo state (branch, changed files, commits) with no assistant call. |
315
- | `lemma-brain-ingest [projectRoot] [--changelog] [--team-pull]` | Feed The Brain from git commits and `CHANGELOG.md`, incrementally; `--team-pull` imports the repo's `.lemma-brain/`. |
316
- | `lemma-brain-ingest --prompt-submit` | Read a Claude Code `UserPromptSubmit` payload on stdin and reply with the memories that bear on the prompt (id, age, freshness) plus, for a "what is pending" question, a reminder to verify live git/CI state โ€” or nothing. Also surfaces the last session's store draft and a stale MCP build, once each. |
317
- | `lemma-brain-ingest --hook-result [--host=claude\|codex\|cursor\|opencode]` | Read a host post-tool payload on stdin: capture red โ†’ green fixes from the agent's own shell, and reply with a Brain note (memory ids, failed attempts, known fixes) in that host's format โ€” or nothing. |
318
-
319
- Wire the standalone bins into hooks so memory doesn't depend on the assistant remembering to call a tool:
85
+ | Claude Code, Cursor, Codex, OpenCode, Windsurf, Kiro | `lemma init` in the project |
86
+ | Muse | Installed on `npm i -g`; `lemma call <tool> '<json>'` works from any shell |
87
+ | Claude Desktop / any MCP client | `{ "command": "npx", "args": ["-y", "@nxuss/lemma", "mcp"] }` |
320
88
 
321
- ```jsonc
322
- // ~/.claude/settings.json
323
- { "hooks": { "SessionEnd": [{ "hooks": [{ "type": "command",
324
- "command": "lemma-checkpoint \"${CLAUDE_PROJECT_DIR:-$PWD}\"" }] }] } }
325
- ```
89
+ `lemma init` also installs the hooks that feed the Brain (git `post-commit` / `post-merge` /
90
+ `post-checkout`, and post-tool hooks for Claude Code, Codex, Cursor and OpenCode). In Claude Code
91
+ it adds a `SessionStart` briefing and a prompt-time recall too, and pre-approves the read and
92
+ memory tools so using them never costs a permission prompt. Existing hooks are kept; `--no-hooks`
93
+ skips them. An install from an older version gets the missing Claude Code hooks the next time the
94
+ MCP server starts; re-run `lemma init` after upgrading to refresh the agent rules. Health check:
95
+ `lemma doctor`.
326
96
 
327
- ```jsonc
328
- // .claude/settings.local.json โ€” what `lemma init` writes: fixes from Claude Code's own Bash
329
- // become memories, and native Read/Edit/Bash get Brain notes back
330
- { "hooks": { "PostToolUse": [{ "matcher": "Bash|Read|Edit|MultiEdit|Write|NotebookEdit",
331
- "hooks": [{ "type": "command", "command": "lemma-brain-ingest --hook-result" }] }] } }
332
- ```
97
+ ### CLI
333
98
 
334
- ```jsonc
335
- // โ€ฆand the same file gets the recall-before-answer hook (no matcher: it fires on every prompt)
336
- { "hooks": { "UserPromptSubmit": [{ "hooks": [{ "type": "command",
337
- "command": "lemma-brain-ingest --prompt-submit" }] }] } }
338
- ```
99
+ | Command | What it does |
100
+ | :--- | :--- |
101
+ | `lemma init` | Configure MCP and hooks for this project |
102
+ | `lemma start` / `stop` / `status` | Proxy + dashboard on `localhost:8081` (an MCP server starts it on its own when none is running) |
103
+ | `lemma stats` | Net token and cost report |
104
+ | `lemma mcp` | Run the MCP server on stdio |
105
+ | `lemma call <tool> [json]` | Call one tool from a shell, for CLIs without MCP |
106
+ | `lemma doctor` | Check the installation |
107
+ | `lemma activate <key>` | Activate Pro |
339
108
 
340
- Attach external state when you store something whose truth depends on it, so `verify_memory` can
341
- tell when it goes stale:
109
+ ### Configuration
342
110
 
343
111
  ```jsonc
344
- // store_memory arguments (excerpt)
345
- { "refs": [
346
- { "kind": "commit", "sha": "2c8a8cb" }, // holds while an ancestor of HEAD
347
- { "kind": "mr", "provider": "gitlab", "id": "1061", "state": "merged" } // stale once its state differs
348
- ] }
349
- ```
350
-
351
- Codex (`~/.codex/hooks.json`, `--host=codex`), Cursor (`~/.cursor/hooks.json`, `postToolUse` +
352
- `postToolUseFailure`, `--host=cursor`) and OpenCode (a plugin in `~/.config/opencode/plugins/`) are
353
- wired the same way by `lemma init` when their config directory exists. Existing hooks are kept;
354
- a file that isn't valid JSON is left alone and the snippet printed instead.
355
-
356
- The git side needs nothing by hand either: `lemma init` installs `post-commit` (commit โ†’ memory) and
357
- `post-merge`/`post-checkout` (pull the team's `.lemma-brain/`). With a versioned hooks dir
358
- (`core.hooksPath`, e.g. husky) it prints the lines to add instead of editing team files.
359
-
360
- Customize via `lemma.config.json`:
361
-
362
- ```json
112
+ // lemma.config.json
363
113
  {
364
- "system": { "clipboardWatcher": { "disabled": false } },
365
- "mcp": { "allowedCommandPrefixes": ["npm", "git", "tsc", "your-custom-tool"] }
114
+ "mcp": {
115
+ "toolProfile": "auto", // "auto" | "core" | "full"
116
+ "allowedCommandPrefixes": ["npm", "git", "tsc"],
117
+ "sandbox": { "mode": "docker", "image": "node:22-bookworm", "network": "none" }
118
+ },
119
+ "system": { "clipboardWatcher": { "disabled": false } }
366
120
  }
367
121
  ```
368
122
 
369
- ---
123
+ `LEMMA_BRAIN_ENCRYPT=1` stores the Brain AES-256-GCM encrypted at rest. Security-related
124
+ environment variables are documented in [`.env.security.example`](.env.security.example).
370
125
 
371
- ## ๐Ÿ”Œ MCP integration
372
-
373
- | Client | Setup |
374
- | :--- | :--- |
375
- | **Muse** (`muse` CLI ยท Muse Spark) | `lemma init` installs the skill into your **user** catalog (`muse skills install --scope user`, auto-loads in every session) + project skill; `npm i -g @nxuss/lemma` also registers it via postinstall. `lemma call` wrapper via `bash` (no MCP native needed). Health check: `lemma doctor`. |
376
- | OpenCode | `lemma init` โ€” registers itself in `~/.opencode.json`, zero config. |
377
- | Cursor / Windsurf / Kiro / Antigravity | Settings โ†’ MCP โ†’ add server, command `lemma mcp`. |
378
- | Claude Desktop | Add to `mcpServers`: `{ "lemma": { "command": "npx", "args": ["-y", "@nxuss/lemma", "mcp"] } }` |
379
- | Claude Code / Codex CLI | `lemma init` โ€” auto-configures MCP + sets gateway (`ANTHROPIC_BASE_URL`/`OPENAI_BASE_URL` โ†’ `http://localhost:8081`). |
380
-
381
- Once connected, Lemma auto-injects its TurboMode system prompt on handshake โ€” states the goal
382
- (reduce what enters context without ever costing a correct answer) and enforces it: a tool call
383
- must save more than its own round-trip, `smarter_cache` hits are disclosed as cached and
384
- re-verified before being acted on, `store_memory` only fires after a solution is verified, and
385
- compression is always for the model's own context โ€” the user gets the real file.
386
-
387
- ---
388
-
389
- ## ๐Ÿ“ก MCP resources
390
-
391
- | Resource URI | Description |
392
- | :--- | :--- |
393
- | `lemma://runtime/context` | Live application errors, stack traces, and runtime state. |
394
- | `lemma://stats/usage` | Current token savings, cost report, and cache hit metrics. |
395
- | `lemma://project/context` | Active project metadata, tech stack, memory count. |
396
- | `lemma://project/onboarding` | Dynamic project architecture guide. |
397
- | `lemma://multiverse/timeline` | Chronological AST diff timeline of recent snapshots. |
398
-
399
- ---
400
-
401
- ## ๐Ÿ”’ Security
402
-
403
- **Network binding.** Binds only to `127.0.0.1` by default โ€” not network-accessible unless you set
404
- `LEMMA_BIND_HOST=0.0.0.0` and enable `AUTH_ENABLED`/`AUTH_REQUIRE_API_KEY`/`AUTH_ALLOWED_ORIGINS`.
405
-
406
- **Command allowlist.** `run_workspace_command` is deny-by-default, with defaults covering normal
407
- JS/TS, Python, Go, Rust, Ruby, JVM, `make`, git/gh, read-only shell utilities, and container/infra
408
- CLIs. Extend via `lemma.config.json` โ†’ `mcp.allowedCommandPrefixes`. See
409
- [`.env.security.example`](.env.security.example) for every security-related env var.
410
-
411
- **What commands can reach.** Two guards apply by default, on macOS, Linux and Windows:
412
-
413
- - *Environment.* Commands no longer inherit the host's whole environment (tokens, API keys, the
414
- license key). They get `PATH`, home/temp dirs, locale, terminal and toolchain-location variables
415
- only. If a command needs more (for example `HTTPS_PROXY`), allow it by name, or restore the old
416
- behavior:
417
-
418
- ```json
419
- { "mcp": { "commandEnv": { "allow": ["HTTPS_PROXY"] } } }
420
- { "mcp": { "commandEnv": { "mode": "inherit" } } }
421
- ```
422
-
423
- - *Paths.* `cat`, `head`, `tail`, `ls`, `find`, `grep`, `rg`, `sed`, `awk`, `diff`, `sort`, `wc` and
424
- similar must keep their file operands inside the workspace: absolute paths, `~`, `..` that climb
425
- out, environment variables in a path, and symlinks pointing outside are refused.
426
-
427
- Those two are guards, not a sandbox: commands that run code (`node -e`, `python -c`, `npm run`,
428
- `git -C โ€ฆ`) can still reach anything the user can. For real isolation, opt in to the Docker sandbox
429
- (Docker is the one layer that works the same on macOS, Linux and Windows):
430
-
431
- ```json
432
- { "mcp": { "sandbox": { "mode": "docker", "image": "node:22-bookworm", "network": "none" } } }
433
- ```
434
-
435
- Each validated command then runs in a throwaway container that sees only the workspace (mounted at
436
- `/workspace`), with no network (`"network": "bridge"` allows it, for `npm install` or `git fetch`),
437
- none of the host's environment, no capabilities, a read-only root filesystem, and bounded memory,
438
- CPUs and processes (`memory`, `cpus`, `pidsLimit`). Files it creates belong to you, not to root.
439
- It fails closed: if Docker is down or the image is missing, the command is **not** run on the host.
440
-
441
- The image must contain the toolchain your commands use (`node:22-bookworm` has node, npm, git,
442
- python3, make and gcc; there is no `cargo` or `go`). Run `docker pull <image>` once beforehand,
443
- since a first download counts against the command's timeout.
444
-
445
- **Confirmations.** `run_workspace_command`, `apply_workspace_patch` and `forget_memory` no longer
446
- ask the host for a second "Proceed?" by default โ€” the allowlist, the rejection of shell chaining and
447
- the workspace-root path checks are what protect you, and your host has its own permission layer. To
448
- require the extra prompt: `{ "mcp": { "confirmActions": true } }` in `lemma.config.json`.
449
-
450
- **Brain at rest.** Secrets are redacted one-way before a memory is indexed or persisted
451
- (scrub-on-store, same patterns as the traffic firewall โ€” the token map is discarded, there is
452
- no unmask step). `LEMMA_BRAIN_ENCRYPT=1` additionally stores the corpus AES-256-GCM encrypted
453
- under `<brainDir>/.brain.key` (0600, auto-generated); `LEMMA_BRAIN_KEY` (64 hex chars or base64
454
- of 32 bytes) overrides it for teams sharing one key. A malformed key fails loud at startup;
455
- a wrong key flows into the integrity fallback (backup โ†’ quarantine โ†’ fresh start), never an
456
- exception, never half a corpus.
457
-
458
- ---
459
-
460
- ## ๐Ÿฆœ SDK integrations & proxy mode
461
-
462
- ```typescript
463
- import { LemmaCrewAIProvider } from '@nxuss/lemma/crewai';
464
- const crew = new LemmaCrewAIProvider({ agents: [...] });
465
- ```
126
+ ### Proxy mode (optional)
466
127
 
467
- Point any OpenAI-compatible tool at `http://localhost:8081/v1` for transparent caching and privacy
468
- (Cursor: Settings โ†’ Models โ†’ Override Base URL; VS Code/Continue: `apiBase`).
128
+ Point any OpenAI-compatible client at `http://localhost:8081/v1` to add an exact + semantic
129
+ response cache and the same privacy masking to your API traffic. Cached answers are kept per
130
+ project, never served across projects.
469
131
 
470
132
  ---
471
133
 
472
- MIT ยฉ Nxus Studio | [Upgrade to Lemma Pro](https://lemma.nxus.studio/upgrade)
134
+ Changelog: [`CHANGELOG.md`](CHANGELOG.md) ยท MIT ยฉ Nxus Studio ยท [Lemma Pro](https://lemma.nxus.studio/upgrade)
@@ -99,8 +99,30 @@ function promptSubmit() {
99
99
  if (out) process.stdout.write(out);
100
100
  }
101
101
 
102
+ // SessionStart hook (Claude Code): the Brain's briefing and the Lemma playbook, in context
103
+ // before the first prompt โ€” no tool call for the agent to remember or skip.
104
+ function sessionStart() {
105
+ const dist = path.join(__dirname, '..', 'dist', 'cjs');
106
+ let sessionBriefing, formatHostOutput;
107
+ try {
108
+ ({ sessionBriefing } = require(path.join(dist, 'subconscious', 'HostRecall.js')));
109
+ ({ formatHostOutput } = require(path.join(dist, 'subconscious', 'HostAdapters.js')));
110
+ } catch {
111
+ return;
112
+ }
113
+ let payload = {};
114
+ try {
115
+ payload = JSON.parse(readStdin()) || {};
116
+ } catch {
117
+ // No payload is fine: the briefing only needs a directory.
118
+ }
119
+ const out = formatHostOutput('claude', sessionBriefing(payload, payload.cwd), 'SessionStart');
120
+ if (out) process.stdout.write(out);
121
+ }
122
+
102
123
  function main() {
103
124
  const args = process.argv.slice(2);
125
+ if (args.includes('--session-start')) return sessionStart();
104
126
  if (args.includes('--prompt-submit')) return promptSubmit();
105
127
  if (args.includes('--hook-result')) return hookResult(args);
106
128
  const maxIndex = args.indexOf('--max');