@nxuss/lemma 1.28.0 → 1.30.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 +41 -8
- package/bin/brain-ingest.js +34 -14
- package/dashboard/dist/assets/index-Dh-whqJ7.js +481 -0
- package/dashboard/dist/assets/index-Dh-whqJ7.js.map +1 -0
- package/dashboard/dist/assets/{index-DtEKr0hI.css → index-Yt1H2B7F.css} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/cjs/cli/hostHooks.d.ts +59 -0
- package/dist/cjs/cli/hostHooks.d.ts.map +1 -0
- package/dist/cjs/cli/hostHooks.js +235 -0
- package/dist/cjs/cli/hostHooks.js.map +1 -0
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +31 -1
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/memory.js +1 -0
- package/dist/cjs/mcp/tools/memory.js.map +1 -1
- package/dist/cjs/subconscious/HostAdapters.d.ts +45 -0
- package/dist/cjs/subconscious/HostAdapters.d.ts.map +1 -0
- package/dist/cjs/subconscious/HostAdapters.js +219 -0
- package/dist/cjs/subconscious/HostAdapters.js.map +1 -0
- package/dist/cjs/subconscious/HostRecall.d.ts +44 -0
- package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -0
- package/dist/cjs/subconscious/HostRecall.js +186 -0
- package/dist/cjs/subconscious/HostRecall.js.map +1 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts +21 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +24 -2
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/utils/FixCapture.d.ts +8 -0
- package/dist/cjs/utils/FixCapture.d.ts.map +1 -1
- package/dist/cjs/utils/FixCapture.js +14 -3
- package/dist/cjs/utils/FixCapture.js.map +1 -1
- package/dist/esm/cli/hostHooks.d.ts +59 -0
- package/dist/esm/cli/hostHooks.d.ts.map +1 -0
- package/dist/esm/cli/hostHooks.js +223 -0
- package/dist/esm/cli/hostHooks.js.map +1 -0
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +31 -1
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
- package/dist/esm/mcp/tools/memory.js +1 -0
- package/dist/esm/mcp/tools/memory.js.map +1 -1
- package/dist/esm/subconscious/HostAdapters.d.ts +45 -0
- package/dist/esm/subconscious/HostAdapters.d.ts.map +1 -0
- package/dist/esm/subconscious/HostAdapters.js +208 -0
- package/dist/esm/subconscious/HostAdapters.js.map +1 -0
- package/dist/esm/subconscious/HostRecall.d.ts +44 -0
- package/dist/esm/subconscious/HostRecall.d.ts.map +1 -0
- package/dist/esm/subconscious/HostRecall.js +178 -0
- package/dist/esm/subconscious/HostRecall.js.map +1 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts +21 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +24 -2
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/utils/FixCapture.d.ts +8 -0
- package/dist/esm/utils/FixCapture.d.ts.map +1 -1
- package/dist/esm/utils/FixCapture.js +13 -3
- package/dist/esm/utils/FixCapture.js.map +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/index-DiidVeI5.js +0 -481
- package/dashboard/dist/assets/index-DiidVeI5.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://github.com/Nxusbets/lemma)
|
|
6
6
|
[](https://github.com/Nxusbets/lemma)
|
|
7
7
|
[](https://github.com/Nxusbets/lemma)
|
|
8
|
-
[](https://github.com/Nxusbets/lemma)
|
|
9
9
|
|
|
10
10
|
```text
|
|
11
11
|
__
|
|
@@ -35,6 +35,23 @@ lemma start # gateway + dashboard on http://localhost:8081
|
|
|
35
35
|
>
|
|
36
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
37
|
>
|
|
38
|
+
> **🆕 v1.30.0 — the Brain speaks through your agent's own tools, for zero tokens.** Agents read,
|
|
39
|
+
> edit and test with their native tools, so the Brain used to stay silent unless the model
|
|
40
|
+
> remembered `search_memory`. Now a post-tool hook answers at the three moments a memory is worth
|
|
41
|
+
> the most: reading a file the Brain has notes on (their ids), editing code where an approach
|
|
42
|
+
> already **failed**, and a test/build/lint failing with an error the Brain has a recorded **fix**
|
|
43
|
+
> for. Local BM25 + hashes, no model tokens; ids and one line only (~35 tokens), and silent by
|
|
44
|
+
> default — no match, a stale fix, or a note already given this session says nothing. `lemma init`
|
|
45
|
+
> wires it for **Claude Code, Codex, Cursor and OpenCode**. Also fixes `store()`'s dedup leaking
|
|
46
|
+
> across projects (the same fix in a second repo was dropped as a "duplicate").
|
|
47
|
+
>
|
|
48
|
+
> **🆕 v1.29.0 — the dashboard shows what the Brain knows.** `lemma start` now opens with a
|
|
49
|
+
> 🧠 Brain panel: how many files of your codebase it carries evidence about, how many times a
|
|
50
|
+
> memory reached an agent's context, growth this week, how much of it is verifiable against the
|
|
51
|
+
> code, where memories come from (manual, red → green fixes, tests, commits, team), and the most
|
|
52
|
+
> recalled ones. Token savings stay as a footnote — the Brain's value is agents not re-discovering
|
|
53
|
+
> context. Same numbers in `brain_stats` and at `GET /api/brain/stats`.
|
|
54
|
+
>
|
|
38
55
|
> **🆕 v1.28.0 — the Brain goes team-wide through git, and fills itself.** `brain_team push`
|
|
39
56
|
> writes your verified memories into the repo (`.lemma-brain/memories/`, one reviewable JSON file
|
|
40
57
|
> each, paths relative to the repo root); `brain_team pull` — automatic on merge/checkout once
|
|
@@ -84,6 +101,16 @@ lemma start # gateway + dashboard on http://localhost:8081
|
|
|
84
101
|
it, never one without the other). `store_memory` derives `filePaths`/`symbols` by default from
|
|
85
102
|
whatever the session already read, wrote, or patched when the caller doesn't pass them —
|
|
86
103
|
flagged as auto-derived in the response, correctable, but no longer opt-in.
|
|
104
|
+
- **A Brain that speaks up on its own, through the host's tools** — a post-tool hook
|
|
105
|
+
(`lemma-brain-ingest --hook-result --host=claude|codex|cursor|opencode`) points at memories when
|
|
106
|
+
the agent reads a file they're about to matter for, warns when an edit touches a documented
|
|
107
|
+
failed attempt, and names the recorded fix when a verdict command fails with an error already
|
|
108
|
+
fixed in *this* project (term overlap between error headlines decides "the same failure", not
|
|
109
|
+
BM25 rank). No model tokens to compute, ids instead of bodies, deduped per host session, and a
|
|
110
|
+
pointer never counts as reuse. Codex's shell reads (`cat`, `sed -n`, …) and `apply_patch` edits
|
|
111
|
+
are recovered from the command; OpenCode gets a plugin, since it has no hook protocol.
|
|
112
|
+
Windsurf/Devin post-hooks can't inject context, and Kiro's hooks spend tokens by design, so
|
|
113
|
+
neither is wired.
|
|
87
114
|
- **A team Brain, shared through git** — `brain_team push` writes this project's fresh, tracked
|
|
88
115
|
memories to `.lemma-brain/memories/<id>.json`: one sorted-key JSON file per memory, so two people
|
|
89
116
|
sharing at once never conflict, every shared memory goes through code review, and deleting one is
|
|
@@ -194,8 +221,8 @@ lemma_toolbox { "action": "call", "tool": "terraform_drift", "args": {} }
|
|
|
194
221
|
|
|
195
222
|
| Command | Action |
|
|
196
223
|
| :--- | :--- |
|
|
197
|
-
| `lemma init` | Bootstraps config, auto-configures MCP for OpenCode, Claude Desktop, Cursor, Windsurf, Kiro, VS Code, and installs the
|
|
198
|
-
| `lemma start` | Launches proxy, cache engine, and dashboard at `http://localhost:8081
|
|
224
|
+
| `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). |
|
|
225
|
+
| `lemma start` | Launches proxy, cache engine, and dashboard at `http://localhost:8081` (gateway savings + Brain knowledge panel). |
|
|
199
226
|
| `lemma stop` / `lemma status` / `lemma stats` | Stop, health check, and net token/cost report (reports `NET COST` when a session is underwater). |
|
|
200
227
|
| `lemma mcp` | Starts the stdin/stdout MCP server for IDE integration. |
|
|
201
228
|
| `lemma heal` / `lemma autopilot` / `lemma watch` | Diagnose+repair the last crash / toggle autonomous fix-apply / silent patch-only watcher. |
|
|
@@ -203,7 +230,7 @@ lemma_toolbox { "action": "call", "tool": "terraform_drift", "args": {} }
|
|
|
203
230
|
| `lemma activate <key>` | Activate a Pro license. |
|
|
204
231
|
| `lemma-checkpoint [projectRoot]` | Derive a session checkpoint from repo state (branch, changed files, commits) with no assistant call. |
|
|
205
232
|
| `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/`. |
|
|
206
|
-
| `lemma-brain-ingest --hook-result` | Read a host
|
|
233
|
+
| `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. |
|
|
207
234
|
|
|
208
235
|
Wire the standalone bins into hooks so memory doesn't depend on the assistant remembering to call a tool:
|
|
209
236
|
|
|
@@ -214,12 +241,18 @@ Wire the standalone bins into hooks so memory doesn't depend on the assistant re
|
|
|
214
241
|
```
|
|
215
242
|
|
|
216
243
|
```jsonc
|
|
217
|
-
// .claude/settings.json —
|
|
218
|
-
|
|
219
|
-
|
|
244
|
+
// .claude/settings.local.json — what `lemma init` writes: fixes from Claude Code's own Bash
|
|
245
|
+
// become memories, and native Read/Edit/Bash get Brain notes back
|
|
246
|
+
{ "hooks": { "PostToolUse": [{ "matcher": "Bash|Read|Edit|MultiEdit|Write|NotebookEdit",
|
|
247
|
+
"hooks": [{ "type": "command", "command": "lemma-brain-ingest --hook-result" }] }] } }
|
|
220
248
|
```
|
|
221
249
|
|
|
222
|
-
|
|
250
|
+
Codex (`~/.codex/hooks.json`, `--host=codex`), Cursor (`~/.cursor/hooks.json`, `postToolUse` +
|
|
251
|
+
`postToolUseFailure`, `--host=cursor`) and OpenCode (a plugin in `~/.config/opencode/plugins/`) are
|
|
252
|
+
wired the same way by `lemma init` when their config directory exists. Existing hooks are kept;
|
|
253
|
+
a file that isn't valid JSON is left alone and the snippet printed instead.
|
|
254
|
+
|
|
255
|
+
The git side needs nothing by hand either: `lemma init` installs `post-commit` (commit → memory) and
|
|
223
256
|
`post-merge`/`post-checkout` (pull the team's `.lemma-brain/`). With a versioned hooks dir
|
|
224
257
|
(`core.hooksPath`, e.g. husky) it prints the lines to add instead of editing team files.
|
|
225
258
|
|
package/bin/brain-ingest.js
CHANGED
|
@@ -14,13 +14,20 @@
|
|
|
14
14
|
* and never double-store. `--max N` only matters the first time there is no marker yet.
|
|
15
15
|
*
|
|
16
16
|
* Usage: lemma-brain-ingest [projectRoot] [--max N] [--changelog] [--no-commits] [--team-pull]
|
|
17
|
-
* lemma-brain-ingest --hook-result < payload.json
|
|
17
|
+
* lemma-brain-ingest --hook-result [--host=claude|codex|cursor|opencode] < payload.json
|
|
18
18
|
*
|
|
19
19
|
* --team-pull Import the repo's shared memories from .lemma-brain/ (post-merge/post-checkout).
|
|
20
|
-
* --hook-result Read a host PostToolUse hook payload on stdin (Claude Code
|
|
21
|
-
* feed
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* --hook-result Read a host PostToolUse hook payload on stdin (Claude Code shape) and:
|
|
21
|
+
* - feed a Bash run to FixCapture, so a test that goes red → green through the
|
|
22
|
+
* agent's own shell becomes a memory too;
|
|
23
|
+
* - answer with a HostRecall note (as `additionalContext`, the only PostToolUse
|
|
24
|
+
* output the host puts in the model's context) when a Read touches a file the
|
|
25
|
+
* Brain has memories about, an edit touches a documented failed attempt, or a
|
|
26
|
+
* failing verdict command matches a recorded fix. Silent otherwise.
|
|
27
|
+
* --host=claude|codex|cursor|opencode picks the payload/reply dialect
|
|
28
|
+
* (default claude; see src/subconscious/HostAdapters.ts).
|
|
29
|
+
* `lemma init` wires it for each host it finds, e.g. .claude/settings.local.json:
|
|
30
|
+
* "hooks": { "PostToolUse": [{ "matcher": "Bash|Read|Edit|MultiEdit|Write|NotebookEdit",
|
|
24
31
|
* "hooks": [{ "type": "command", "command": "lemma-brain-ingest --hook-result" }] }] }
|
|
25
32
|
*/
|
|
26
33
|
|
|
@@ -34,27 +41,40 @@ function readStdin() {
|
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
|
|
37
|
-
function hookResult() {
|
|
38
|
-
const
|
|
39
|
-
let recordHookPayload;
|
|
44
|
+
function hookResult(args) {
|
|
45
|
+
const dist = path.join(__dirname, '..', 'dist', 'cjs');
|
|
46
|
+
let recordHookPayload, recallForHookPayload, normalizeHostPayload, formatHostOutput, parseHost;
|
|
40
47
|
try {
|
|
41
|
-
({ recordHookPayload } = require(
|
|
48
|
+
({ recordHookPayload } = require(path.join(dist, 'utils', 'FixCapture.js')));
|
|
49
|
+
({ recallForHookPayload } = require(path.join(dist, 'subconscious', 'HostRecall.js')));
|
|
50
|
+
({ normalizeHostPayload, formatHostOutput, parseHost } = require(path.join(dist, 'subconscious', 'HostAdapters.js')));
|
|
42
51
|
} catch {
|
|
43
52
|
return; // no build — a hook must stay silent and harmless
|
|
44
53
|
}
|
|
45
|
-
|
|
54
|
+
const hostArg = args.find((a) => a.startsWith('--host='));
|
|
55
|
+
const host = parseHost(hostArg ? hostArg.slice('--host='.length) : undefined);
|
|
56
|
+
let raw;
|
|
46
57
|
try {
|
|
47
|
-
|
|
58
|
+
raw = JSON.parse(readStdin());
|
|
48
59
|
} catch {
|
|
49
60
|
return;
|
|
50
61
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
62
|
+
const notes = [];
|
|
63
|
+
for (const payload of normalizeHostPayload(host, raw)) {
|
|
64
|
+
try {
|
|
65
|
+
const res = recordHookPayload(payload, payload.cwd);
|
|
66
|
+
if (res && res.captured) console.error(res.note.trim());
|
|
67
|
+
} catch { /* capture failing must not cost the recall below */ }
|
|
68
|
+
const note = recallForHookPayload(payload, payload.cwd);
|
|
69
|
+
if (note && !notes.includes(note)) notes.push(note);
|
|
70
|
+
}
|
|
71
|
+
const out = formatHostOutput(host, notes.join('\n'));
|
|
72
|
+
if (out) process.stdout.write(out);
|
|
53
73
|
}
|
|
54
74
|
|
|
55
75
|
function main() {
|
|
56
76
|
const args = process.argv.slice(2);
|
|
57
|
-
if (args.includes('--hook-result')) return hookResult();
|
|
77
|
+
if (args.includes('--hook-result')) return hookResult(args);
|
|
58
78
|
const maxIndex = args.indexOf('--max');
|
|
59
79
|
const maxCommits = maxIndex >= 0 ? parseInt(args[maxIndex + 1], 10) : undefined;
|
|
60
80
|
const includeChangelog = args.includes('--changelog');
|