@nxuss/lemma 1.21.0 → 1.22.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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lemma
3
- description: Lemma — cache semántico, firewall de privacidad y memoria cross-sesión para Muse. Usa `lemma call <tool>` vía bash para acceder a 70+ tools sin MCP nativo.
3
+ description: Lemma — cache semántico, firewall de privacidad y memoria cross-sesión para Muse. Usa `lemma call <tool>` vía bash para acceder a 70+ tools sin MCP nativo. Cárgala al iniciar cada sesión: search_memory antes de razonar, store_memory al verificar una solución.
4
4
  user-invocable: true
5
5
  allowed-tools: bash
6
6
  ---
@@ -33,19 +33,20 @@ Si Lemma no encaja, usa tu tool nativo. No fuerces Lemma donde no aporta.
33
33
 
34
34
  ## Cómo llamar a Lemma desde Muse (preferido)
35
35
 
36
- Usa el wrapper `lemma call` — evita craft de JSON-RPC manual y escapa args por ti. Está disponible como `node ./lemma-proxy.cjs call` o `node ./bin/lemma-call.js` o `npx @nxuss/lemma call` si instalaste global.
36
+ Usa el wrapper `lemma call` — evita craft de JSON-RPC manual y escapa args por ti. Está disponible como `lemma call` (instalación global por npm), `npx @nxuss/lemma call`, o local `node ./lemma-proxy.cjs call` / `node ./bin/lemma-call.js`.
37
37
 
38
38
  ```bash
39
39
  # 1. Lookup en memoria antes de razonar (preferido — wrapper)
40
- node ./lemma-proxy.cjs call search_memory --query "tu pregunta"
40
+ lemma call search_memory --query "tu pregunta"
41
41
  # o JSON explícito:
42
- node ./lemma-proxy.cjs call search_memory '{"query":"tu pregunta"}'
42
+ lemma call search_memory '{"query":"tu pregunta"}'
43
+ # (en este repo también vale: node ./lemma-proxy.cjs call search_memory --query "tu pregunta")
43
44
 
44
45
  # 2. Busca en workspace (con scrubbing)
45
- node ./lemma-proxy.cjs call search_workspace --query "texto" --maxResults 10
46
+ lemma call search_workspace --query "texto" --maxResults 10
46
47
 
47
48
  # 3. Guarda solución verificada
48
- node ./lemma-proxy.cjs call store_memory '{"content":"solución verificada","tags":["bugfix"]}'
49
+ lemma call store_memory '{"content":"solución verificada","tags":["bugfix"]}'
49
50
 
50
51
  # 4. Lista tools disponibles
51
52
  node ./lemma-proxy.cjs call --list
@@ -122,3 +123,4 @@ npm i -D @nxuss/lemma && npx lemma init
122
123
  ```
123
124
 
124
125
  > Generado por `lemma init` — @nxuss/lemma para Muse.
126
+ <!-- managed by lemma init (@nxuss/lemma): re-run lemma init after upgrading to refresh -->
package/README.md CHANGED
@@ -27,11 +27,13 @@ to an auditable ledger, never an estimate.
27
27
 
28
28
  ```bash
29
29
  npm install -g @nxuss/lemma
30
- lemma init # auto-configures MCP for your IDE (Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode)
30
+ lemma init # auto-configures MCP for your IDE (Muse, Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode)
31
31
  lemma start # gateway + dashboard on http://localhost:8081
32
32
  ```
33
33
 
34
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`.
35
37
 
36
38
  ---
37
39
 
@@ -156,7 +158,7 @@ Customize via `lemma.config.json`:
156
158
 
157
159
  | Client | Setup |
158
160
  | :--- | :--- |
159
- | **Muse** (`muse` CLI · Muse Spark) | **Zero-config** clone this repo and open with `muse`; skill at `.agents/skills/lemma/SKILL.md` auto-loads, `lemma call` wrapper via `bash` (no MCP native needed). No `lemma init` required. |
161
+ | **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`. |
160
162
  | OpenCode | `lemma init` — registers itself in `~/.opencode.json`, zero config. |
161
163
  | Cursor / Windsurf / Kiro / Antigravity | Settings → MCP → add server, command `lemma mcp`. |
162
164
  | Claude Desktop | Add to `mcpServers`: `{ "lemma": { "command": "npx", "args": ["-y", "@nxuss/lemma", "mcp"] } }` |
package/bin/doctor.js ADDED
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Lemma doctor — verifies the Lemma wiring on this machine / project:
6
+ * wrapper, project skill, user skill (muse), and AGENTS.md block.
7
+ *
8
+ * Usage: `lemma doctor` (exit 0 = usable, exit 1 = wrapper broken).
9
+ */
10
+
11
+ const { execFileSync } = require('child_process');
12
+ const fs = require('fs');
13
+ const os = require('os');
14
+ const path = require('path');
15
+
16
+ const CYAN = '\x1b[36m', GREEN = '\x1b[32m', YELLOW = '\x1b[33m', DIM = '\x1b[2m', RESET = '\x1b[0m', BOLD = '\x1b[1m';
17
+
18
+ function ok(msg) { process.stdout.write(` ${GREEN}✓${RESET} ${msg}\n`); }
19
+ function warn(msg) { process.stdout.write(` ${YELLOW}!${RESET} ${msg}\n`); }
20
+ function fail(msg) { process.stdout.write(` ${YELLOW}✗${RESET} ${msg}\n`); }
21
+
22
+ function shortErr(e) {
23
+ try {
24
+ const raw = (e && (e.stderr || e.stdout || e.message)) || '';
25
+ const line = raw.toString().split('\n').map((s) => s.trim()).filter(Boolean)[0] || '';
26
+ return line.slice(0, 160);
27
+ } catch {
28
+ return '';
29
+ }
30
+ }
31
+
32
+ function museOnPath() {
33
+ try {
34
+ if (process.platform === 'win32') return true;
35
+ require('child_process').execSync('command -v muse', { stdio: 'ignore', timeout: 10000 });
36
+ return true;
37
+ } catch {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ function resolveMcpServer(pkgRoot) {
43
+ const candidates = [
44
+ path.join(pkgRoot, 'dist', 'cjs', 'mcp', 'index.js'),
45
+ path.join(pkgRoot, 'mcp-server.js'),
46
+ ];
47
+ return candidates.find((p) => fs.existsSync(p)) || null;
48
+ }
49
+
50
+ async function main() {
51
+ const pkgRoot = path.join(__dirname, '..');
52
+ const cwd = process.cwd();
53
+ let broken = false;
54
+ process.stdout.write(`\n ${BOLD}${CYAN}Lemma Doctor${RESET}\n\n`);
55
+
56
+ // 1. Wrapper + tool catalog (the core: everything else is advice).
57
+ const server = resolveMcpServer(pkgRoot);
58
+ if (!server) {
59
+ fail('no MCP server found (dist/cjs/mcp/index.js nor mcp-server.js) — run npm run build');
60
+ broken = true;
61
+ } else {
62
+ try {
63
+ const out = execFileSync(process.execPath,
64
+ [path.join(pkgRoot, 'bin', 'lemma-call.js'), '--list'],
65
+ { encoding: 'utf8', timeout: 60000, stdio: ['ignore', 'pipe', 'ignore'] });
66
+ const tools = JSON.parse(out);
67
+ ok(`wrapper works via ${path.relative(pkgRoot, server)} — ${tools.length} tools`);
68
+ } catch {
69
+ fail('wrapper failed: `lemma call --list` did not return a tool catalog');
70
+ broken = true;
71
+ }
72
+ }
73
+
74
+ // 2. Project skill (this repo / project).
75
+ const projSkill = path.join(cwd, '.agents', 'skills', 'lemma', 'SKILL.md');
76
+ if (fs.existsSync(projSkill)) {
77
+ const body = fs.readFileSync(projSkill, 'utf8');
78
+ if (body.includes('Cárgala al iniciar')) ok('project skill current (.agents/skills/lemma/SKILL.md)');
79
+ else warn('project skill is stale (pre auto-load trigger) — re-run `lemma init`');
80
+ } else {
81
+ warn('no project skill — run `lemma init` in this project');
82
+ }
83
+
84
+ // 3. User skill (every `muse` session, any project).
85
+ // Note: inside a project that defines its own `lemma` skill, the CLI shadows
86
+ // the user skill (project wins — by design) and `inspect --source user` then
87
+ // reports "not found". Fall back to the on-disk check before crying missing.
88
+ const configHome = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
89
+ const userSkillFile = path.join(configHome, 'muse', 'skills', 'lemma', 'SKILL.md');
90
+ const projSkillHere = fs.existsSync(projSkill);
91
+ if (!museOnPath()) {
92
+ warn('muse CLI not on PATH — user skill not applicable here');
93
+ } else {
94
+ try {
95
+ execFileSync('muse', ['skills', 'inspect', 'lemma', '--source', 'user'],
96
+ { stdio: 'pipe', timeout: 30000 });
97
+ ok('user skill installed (auto-loads in every muse session)');
98
+ } catch (e) {
99
+ const detail = shortErr(e);
100
+ if (fs.existsSync(userSkillFile) && projSkillHere) {
101
+ ok('user skill installed (shadowed by this project\u2019s skill here — project wins, as designed)');
102
+ } else if (fs.existsSync(userSkillFile)) {
103
+ warn('user skill files exist but the CLI does not see them' + (detail ? ` (${detail})` : ''));
104
+ } else {
105
+ warn('user skill missing' + (detail ? ` (${detail})` : '') + ' — run `lemma init` or `muse skills install <pkg>/.agents/skills/lemma --scope user --force`');
106
+ }
107
+ }
108
+ }
109
+
110
+ // 4. AGENTS.md block (session-start nudge for AGENTS.md-aware agents).
111
+ const agentsPath = path.join(cwd, 'AGENTS.md');
112
+ if (!fs.existsSync(agentsPath) || !fs.readFileSync(agentsPath, 'utf8').includes('@nxuss/lemma')) {
113
+ warn('no Lemma block in ./AGENTS.md — run `lemma init`');
114
+ } else if (fs.readFileSync(agentsPath, 'utf8').includes('At session')) {
115
+ ok('AGENTS.md block current (session-start guard)');
116
+ } else {
117
+ warn('AGENTS.md block is stale (pre Muse guard) — re-run `lemma init`');
118
+ }
119
+
120
+ process.stdout.write(`\n ${DIM}Brain: ~/.lemma-cache/lemma_brain.json · proxy: lemma-proxy.cjs status${RESET}\n\n`);
121
+ return broken ? 1 : 0;
122
+ }
123
+
124
+ if (require.main === module) {
125
+ main().then((code) => process.exit(code)).catch((e) => {
126
+ console.error('doctor failed:', e.message);
127
+ process.exit(1);
128
+ });
129
+ }
130
+
131
+ module.exports = { main };
package/bin/init.js CHANGED
@@ -4,7 +4,7 @@
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
  const os = require('os');
7
- const { execSync, spawn } = require('child_process');
7
+ const { execSync, execFileSync, spawn } = require('child_process');
8
8
 
9
9
  const LEMMA_CACHE = path.join(os.homedir(), '.lemma-cache');
10
10
  const BRAIN_FILE = path.join(LEMMA_CACHE, 'lemma_brain.json');
@@ -436,10 +436,13 @@ The MCP server \`lemma\` is connected. For clients with native MCP support
436
436
  (Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode), NEVER use native tools
437
437
  when a Lemma equivalent exists.
438
438
 
439
- > **Muse Code:** you DO NOT have native \`mcp__lemma__*\` tools. For you,
440
- > \`AGENTS.md\` is advisory. Follow \`.agents/skills/lemma/SKILL.md\` instead
441
- > it has priority and uses \`lemma call\` via bash. Do not enforce the table
442
- > below as a hard block; use it only when \`lemma call\` actually helps.
439
+ > **Muse Code:** you DO NOT have native \`mcp__lemma__*\` tools. At session
440
+ > start, load the \`lemma\` skill (user scope if present, else
441
+ > \`.agents/skills/lemma/SKILL.md\`) and follow it instead of this file it
442
+ > has priority and uses \`lemma call\` via bash. Then call \`search_memory\`
443
+ > with the task topic before reasoning. Do not enforce the table below as a
444
+ > hard block; use \`lemma call\` when it actually helps. If no \`lemma\` skill
445
+ > is installed, tell the user to run \`npx @nxuss/lemma init\`.
443
446
 
444
447
  ## Mandatory Substitutions (MCP-native clients only)
445
448
 
@@ -464,7 +467,7 @@ when a Lemma equivalent exists.
464
467
  2. Call \`search_memory\` with the task topic — recall past solutions
465
468
  3. When done: call \`store_memory\` with the solution
466
469
 
467
- > Muse: use \`node ./lemma-proxy.cjs call <tool>\` (see \`.agents/skills/lemma/SKILL.md\`).
470
+ > Muse: use \`lemma call <tool>\` (or \`node ./lemma-proxy.cjs call <tool>\` in this repo — see \`.agents/skills/lemma/SKILL.md\`).
468
471
 
469
472
  ## Bug Reporting
470
473
 
@@ -574,7 +577,7 @@ function configureKiro() {
574
577
  // OpenCode: register MCP server in opencode.json + Muse skill
575
578
  const MUSE_SKILL_CONTENT = `---
576
579
  name: lemma
577
- description: Lemma — cache semántico, firewall de privacidad y memoria cross-sesión para Muse. Usa lemma call <tool> vía bash para acceder a 70+ tools sin MCP nativo.
580
+ description: Lemma — cache semántico, firewall de privacidad y memoria cross-sesión para Muse. Usa \`lemma call <tool>\` vía bash para acceder a 70+ tools sin MCP nativo. Cárgala al iniciar cada sesión: search_memory antes de razonar, store_memory al verificar una solución.
578
581
  user-invocable: true
579
582
  allowed-tools: bash
580
583
  ---
@@ -607,19 +610,20 @@ Si Lemma no encaja, usa tu tool nativo. No fuerces Lemma donde no aporta.
607
610
 
608
611
  ## Cómo llamar a Lemma desde Muse (preferido)
609
612
 
610
- Usa el wrapper \`lemma call\` — evita craft de JSON-RPC manual y escapa args por ti. Está disponible como \`node ./lemma-proxy.cjs call\` o \`node ./bin/lemma-call.js\` o \`npx @nxuss/lemma call\` si instalaste global.
613
+ Usa el wrapper \`lemma call\` — evita craft de JSON-RPC manual y escapa args por ti. Está disponible como \`lemma call\` (instalación global por npm), \`npx @nxuss/lemma call\`, o local \`node ./lemma-proxy.cjs call\` / \`node ./bin/lemma-call.js\`.
611
614
 
612
615
  \`\`\`bash
613
616
  # 1. Lookup en memoria antes de razonar (preferido — wrapper)
614
- node ./lemma-proxy.cjs call search_memory --query "tu pregunta"
617
+ lemma call search_memory --query "tu pregunta"
615
618
  # o JSON explícito:
616
- node ./lemma-proxy.cjs call search_memory '{"query":"tu pregunta"}'
619
+ lemma call search_memory '{"query":"tu pregunta"}'
620
+ # (en este repo también vale: node ./lemma-proxy.cjs call search_memory --query "tu pregunta")
617
621
 
618
622
  # 2. Busca en workspace (con scrubbing)
619
- node ./lemma-proxy.cjs call search_workspace --query "texto" --maxResults 10
623
+ lemma call search_workspace --query "texto" --maxResults 10
620
624
 
621
625
  # 3. Guarda solución verificada
622
- node ./lemma-proxy.cjs call store_memory '{"content":"solución verificada","tags":["bugfix"]}'
626
+ lemma call store_memory '{"content":"solución verificada","tags":["bugfix"]}'
623
627
 
624
628
  # 4. Lista tools disponibles
625
629
  node ./lemma-proxy.cjs call --list
@@ -696,17 +700,51 @@ npm i -D @nxuss/lemma && npx lemma init
696
700
  \`\`\`
697
701
 
698
702
  > Generado por \`lemma init\` — @nxuss/lemma para Muse.
703
+ <!-- managed by lemma init (@nxuss/lemma): re-run lemma init after upgrading to refresh -->
699
704
  `;
700
705
 
706
+ // Installs the Lemma skill into the user's GLOBAL muse skill catalog so it
707
+ // auto-loads in every `muse` session — not just in projects where `lemma init`
708
+ // was run. Best-effort: never fails `lemma init` — but LOUD about the reason,
709
+ // so a missing user skill is diagnosable instead of silent.
710
+ function shortErr(e) {
711
+ try {
712
+ const raw = (e && (e.stderr || e.stdout || e.message)) || '';
713
+ const line = raw.toString().split('\n').map((s) => s.trim()).filter(Boolean)[0] || '';
714
+ return line.slice(0, 160);
715
+ } catch {
716
+ return '';
717
+ }
718
+ }
719
+
720
+ function configureMuseUserSkill(skillDir) {
721
+ try {
722
+ execSync('command -v muse', { stdio: 'ignore' });
723
+ } catch {
724
+ return { ok: false, reason: 'muse CLI not found on PATH' };
725
+ }
726
+ try {
727
+ execFileSync('muse', ['skills', 'install', skillDir, '--scope', 'user', '--force'],
728
+ { stdio: 'pipe', timeout: 30000 });
729
+ return { ok: true, reason: '' };
730
+ } catch (e) {
731
+ const detail = shortErr(e);
732
+ return { ok: false, reason: 'muse skills install failed' + (detail ? `: ${detail}` : '') };
733
+ }
734
+ }
735
+
701
736
  function configureMuse() {
702
737
  const cwd = process.cwd();
703
738
  const skillDir = path.join(cwd, '.agents', 'skills', 'lemma');
739
+ let project = false;
704
740
  try {
705
741
  ensureDir(skillDir);
706
742
  const skillPath = path.join(skillDir, 'SKILL.md');
707
743
  fs.writeFileSync(skillPath, MUSE_SKILL_CONTENT, 'utf8');
708
- return true;
709
- } catch { return false; }
744
+ project = true;
745
+ } catch { project = false; }
746
+ const userRes = project ? configureMuseUserSkill(skillDir) : { ok: false, reason: 'project skill write failed' };
747
+ return { project, user: userRes.ok, userReason: userRes.reason };
710
748
  }
711
749
 
712
750
  function ensureKiroMigratesAgentsMd() {
@@ -951,9 +989,11 @@ async function main() {
951
989
  configureOpenCode();
952
990
  ok('OpenCode configured (opencode.json MCP + instructions)');
953
991
 
954
- const museOk = configureMuse();
955
- if (museOk) ok('Muse configured (.agents/skills/lemma/SKILL.md)');
956
- else warn('Muse skill could not be configured');
992
+ const museResult = configureMuse();
993
+ if (museResult.project) {
994
+ ok('Muse configured (.agents/skills/lemma/SKILL.md)' + (museResult.user ? ' + user skill (auto-load in every muse session)' : ''));
995
+ if (!museResult.user) warn(`Muse user skill NOT installed — ${museResult.userReason || 'unknown reason'}`);
996
+ } else warn('Muse skill could not be configured');
957
997
 
958
998
  const hasContinue = detectTool('Continue.dev', () => configureContinueDotDev());
959
999
  if (hasContinue) ok('Continue.dev configured');
@@ -1001,6 +1041,7 @@ async function main() {
1001
1041
  process.stderr.write(` ${GREEN}●${RESET} MCP server ready ${DIM}(lemma mcp)${RESET}\n`);
1002
1042
  process.stderr.write(` ${GREEN}●${RESET} Dashboard active ${DIM}(lemma stats)${RESET}\n`);
1003
1043
  process.stderr.write(` ${GREEN}●${RESET} New terminals: env vars auto-loaded\n`);
1044
+ process.stderr.write(` ${DIM}Upkeep: re-run 'lemma init' after upgrading @nxuss/lemma (refreshes skills + rules)${RESET}\n`);
1004
1045
  process.stderr.write(` ${GREEN}●${RESET} Todos los IDE/CLI nuevos ya apuntan al proxy\n`);
1005
1046
  process.stderr.write(` ${gatewayResult.activated ? GREEN + '●' : YELLOW + '○'}${RESET} Claude Code gateway: ${gatewayResult.activated ? 'ACTIVE (model traffic cached)' : 'inactive (MCP tools only)'}\n`);
1006
1047
  process.stderr.write(` ${DIM}──────────────────────────────────────${RESET}\n`);
@@ -1009,7 +1050,11 @@ async function main() {
1009
1050
  process.stderr.write(` ${DIM}Logs: ${LEMMA_CACHE}/proxy-daemon.log${RESET}\n\n`);
1010
1051
  }
1011
1052
 
1012
- main().catch(e => {
1013
- console.error('init failed:', e.message);
1014
- process.exit(1);
1015
- });
1053
+ if (require.main === module) {
1054
+ main().catch(e => {
1055
+ console.error('init failed:', e.message);
1056
+ process.exit(1);
1057
+ });
1058
+ }
1059
+
1060
+ module.exports = { main, configureMuse, configureMuseUserSkill, updateAgentsMd, MUSE_SKILL_CONTENT, LEMMA_RULES_CONTENT };
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Lemma postinstall — registers the Lemma skill in the user's GLOBAL muse
6
+ * catalog so it auto-loads in every `muse` session, with zero extra steps
7
+ * after `npm i [-g] @nxuss/lemma`.
8
+ *
9
+ * Total function: never fails the install, never prints on success, finishes
10
+ * in well under a second when there is nothing to do. No build output needed —
11
+ * skill install only registers a markdown file, it never invokes any tool.
12
+ */
13
+
14
+ const { execSync, execFileSync } = require('child_process');
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+
18
+ function museOnPath() {
19
+ try {
20
+ if (process.platform === 'win32') {
21
+ execFileSync('where', ['muse'], { stdio: 'ignore', timeout: 10000 });
22
+ } else {
23
+ execSync('command -v muse', { stdio: 'ignore', timeout: 10000 });
24
+ }
25
+ return true;
26
+ } catch {
27
+ return false;
28
+ }
29
+ }
30
+
31
+ function main() {
32
+ try {
33
+ const skillDir = path.join(__dirname, '..', '.agents', 'skills', 'lemma');
34
+ if (!fs.existsSync(path.join(skillDir, 'SKILL.md'))) return;
35
+ if (!museOnPath()) return;
36
+ execFileSync('muse', ['skills', 'install', skillDir, '--scope', 'user', '--force'],
37
+ { stdio: 'ignore', timeout: 25000 });
38
+ } catch {
39
+ // Best-effort by contract: npm install must never fail because of this.
40
+ }
41
+ }
42
+
43
+ main();
package/lemma-proxy.cjs CHANGED
@@ -35,7 +35,14 @@ const cmd = process.argv[2];
35
35
 
36
36
  if (cmd === 'init') {
37
37
  const initPath = path.join(__dirname, 'bin', 'init.js');
38
- if (fs.existsSync(initPath)) require(initPath);
38
+ if (fs.existsSync(initPath)) {
39
+ const initMod = require(initPath);
40
+ // bin/init.js self-runs only when executed directly; via this `lemma`
41
+ // binary path it is required, so invoke its exported main().
42
+ if (initMod && typeof initMod.main === 'function') {
43
+ initMod.main().catch(e => { console.error('init failed:', e.message); process.exit(1); });
44
+ }
45
+ }
39
46
  else { console.error('init not found. Run npm run build first.'); process.exit(1); }
40
47
  } else if (cmd === 'stats') {
41
48
  const cliPath = path.join(__dirname, 'bin', 'cli.js');
@@ -67,6 +74,17 @@ if (cmd === 'init') {
67
74
  console.error('lemma-call not found. Run npm run build first.');
68
75
  process.exit(1);
69
76
  }
77
+ } else if (cmd === 'doctor') {
78
+ const doctorPath = path.join(__dirname, 'bin', 'doctor.js');
79
+ if (fs.existsSync(doctorPath)) {
80
+ const doctorMod = require(doctorPath);
81
+ if (doctorMod && typeof doctorMod.main === 'function') {
82
+ doctorMod.main().then((code) => process.exit(code)).catch((e) => {
83
+ console.error('doctor failed:', e.message);
84
+ process.exit(1);
85
+ });
86
+ }
87
+ } else { console.error('doctor not found.'); process.exit(1); }
70
88
  } else if (cmd === 'proxy') {
71
89
  const proxyPath = path.join(__dirname, 'cache-proxy.js');
72
90
  if (fs.existsSync(proxyPath)) require(proxyPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxuss/lemma",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "Intelligent AI Gateway for IDEs & Agents — Semantic cache, Privacy Firewall, Infrastructure Command Center, and Autonomous Cost-Optimization.",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -87,6 +87,8 @@
87
87
  "bin/init.js",
88
88
  "bin/cli.js",
89
89
  "bin/lemma-call.js",
90
+ "bin/postinstall.js",
91
+ "bin/doctor.js",
90
92
  "bin/checkpoint.js",
91
93
  "bin/brain-ingest.js",
92
94
  ".agents/skills/lemma/SKILL.md",
@@ -108,6 +110,7 @@
108
110
  "build:sdks": "npm run sdk:build",
109
111
  "postbuild": "node scripts/post-build.js && node scripts/fix-esm-extensions.js",
110
112
  "prepare": "npm run build:cjs 2>&1 | tail -n 5 || true",
113
+ "postinstall": "node bin/postinstall.js || true",
111
114
  "dev": "npx tsx start-dev.ts",
112
115
  "start": "node dist/cjs/index.js",
113
116
  "test": "jest",