@nxuss/lemma 1.5.0 → 1.7.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 +182 -6
- package/bin/checkpoint.js +49 -0
- package/bin/init.js +21 -2
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +50 -6
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/mcp/index.js +23 -0
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/prompts.d.ts +1 -2
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +34 -129
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/resources.d.ts.map +1 -1
- package/dist/cjs/mcp/resources.js +4 -4
- package/dist/cjs/mcp/resources.js.map +1 -1
- package/dist/cjs/mcp/tool-profiles.d.ts +55 -0
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -0
- package/dist/cjs/mcp/tool-profiles.js +204 -0
- package/dist/cjs/mcp/tool-profiles.js.map +1 -0
- package/dist/cjs/mcp/tools.d.ts +14 -0
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +190 -27
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.d.ts +36 -2
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +104 -23
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/utils/AutoContextBundle.d.ts.map +1 -1
- package/dist/cjs/utils/AutoContextBundle.js +17 -20
- package/dist/cjs/utils/AutoContextBundle.js.map +1 -1
- package/dist/cjs/utils/ContextSqueezer.d.ts.map +1 -1
- package/dist/cjs/utils/ContextSqueezer.js +5 -3
- package/dist/cjs/utils/ContextSqueezer.js.map +1 -1
- package/dist/cjs/utils/ConversationCheckpoint.d.ts +13 -0
- package/dist/cjs/utils/ConversationCheckpoint.d.ts.map +1 -1
- package/dist/cjs/utils/ConversationCheckpoint.js +58 -0
- package/dist/cjs/utils/ConversationCheckpoint.js.map +1 -1
- package/dist/cjs/utils/SavingsLedger.d.ts +38 -1
- package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/cjs/utils/SavingsLedger.js +89 -13
- package/dist/cjs/utils/SavingsLedger.js.map +1 -1
- package/dist/cjs/utils/TestAutofixInterceptor.d.ts.map +1 -1
- package/dist/cjs/utils/TestAutofixInterceptor.js +15 -26
- package/dist/cjs/utils/TestAutofixInterceptor.js.map +1 -1
- package/dist/cjs/utils/reportSavings.d.ts +15 -0
- package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
- package/dist/cjs/utils/reportSavings.js +13 -1
- package/dist/cjs/utils/reportSavings.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +50 -6
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/mcp/index.js +24 -1
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/prompts.d.ts +1 -2
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +33 -128
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/resources.d.ts.map +1 -1
- package/dist/esm/mcp/resources.js +4 -4
- package/dist/esm/mcp/resources.js.map +1 -1
- package/dist/esm/mcp/tool-profiles.d.ts +55 -0
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -0
- package/dist/esm/mcp/tool-profiles.js +196 -0
- package/dist/esm/mcp/tool-profiles.js.map +1 -0
- package/dist/esm/mcp/tools.d.ts +14 -0
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +188 -29
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.d.ts +36 -2
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +103 -23
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/utils/AutoContextBundle.d.ts.map +1 -1
- package/dist/esm/utils/AutoContextBundle.js +17 -20
- package/dist/esm/utils/AutoContextBundle.js.map +1 -1
- package/dist/esm/utils/ContextSqueezer.d.ts.map +1 -1
- package/dist/esm/utils/ContextSqueezer.js +5 -3
- package/dist/esm/utils/ContextSqueezer.js.map +1 -1
- package/dist/esm/utils/ConversationCheckpoint.d.ts +13 -0
- package/dist/esm/utils/ConversationCheckpoint.d.ts.map +1 -1
- package/dist/esm/utils/ConversationCheckpoint.js +57 -0
- package/dist/esm/utils/ConversationCheckpoint.js.map +1 -1
- package/dist/esm/utils/SavingsLedger.d.ts +38 -1
- package/dist/esm/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/esm/utils/SavingsLedger.js +89 -13
- package/dist/esm/utils/SavingsLedger.js.map +1 -1
- package/dist/esm/utils/TestAutofixInterceptor.d.ts.map +1 -1
- package/dist/esm/utils/TestAutofixInterceptor.js +15 -26
- package/dist/esm/utils/TestAutofixInterceptor.js.map +1 -1
- package/dist/esm/utils/reportSavings.d.ts +15 -0
- package/dist/esm/utils/reportSavings.d.ts.map +1 -1
- package/dist/esm/utils/reportSavings.js +12 -1
- package/dist/esm/utils/reportSavings.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
3
4
|
const CHECKPOINT_DIR = '.lemma/session';
|
|
4
5
|
const MAX_CHECKPOINTS = 10;
|
|
5
6
|
function getDir(projectRoot) {
|
|
@@ -43,6 +44,62 @@ export function saveCheckpoint(checkpoint, projectRoot) {
|
|
|
43
44
|
}
|
|
44
45
|
return full;
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Builds and saves a checkpoint from repository state alone.
|
|
49
|
+
*
|
|
50
|
+
* The model-driven path (calling `conversation_checkpoint` with action "save") depends on the
|
|
51
|
+
* assistant remembering to do it at the end of a session, which in practice does not happen —
|
|
52
|
+
* `.lemma/session/` did not exist in this repo across six releases. This derives what it can
|
|
53
|
+
* from git without any model involvement, so a session-end hook can call it unconditionally.
|
|
54
|
+
*
|
|
55
|
+
* It cannot recover decisions or pending tasks — those only exist in the conversation. Those
|
|
56
|
+
* fields stay empty here rather than being invented, and a model-written checkpoint that has
|
|
57
|
+
* them is always the better record when one exists.
|
|
58
|
+
*/
|
|
59
|
+
export function captureAutoCheckpoint(projectRoot, summary) {
|
|
60
|
+
const git = (args) => {
|
|
61
|
+
try {
|
|
62
|
+
// trimEnd, not trim: `git status --porcelain` encodes the status in the first two
|
|
63
|
+
// columns, so stripping leading whitespace would eat the first line's status char
|
|
64
|
+
// and take the first character of its filename with it.
|
|
65
|
+
return execFileSync('git', ['-C', projectRoot, ...args.split(' ')], {
|
|
66
|
+
encoding: 'utf8',
|
|
67
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
68
|
+
}).trimEnd();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const status = git('status --porcelain');
|
|
75
|
+
const branch = git('rev-parse --abbrev-ref HEAD');
|
|
76
|
+
if (!branch)
|
|
77
|
+
return null; // not a git repo — nothing to derive from
|
|
78
|
+
const filesModified = status
|
|
79
|
+
.split('\n')
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.map((l) => l.slice(3).trim())
|
|
82
|
+
.filter(Boolean);
|
|
83
|
+
const recentCommits = git('log -3 --pretty=format:%s').split('\n').filter(Boolean);
|
|
84
|
+
const derived = [
|
|
85
|
+
`Branch: ${branch}`,
|
|
86
|
+
filesModified.length
|
|
87
|
+
? `${filesModified.length} file(s) with uncommitted changes.`
|
|
88
|
+
: 'Working tree clean.',
|
|
89
|
+
recentCommits.length ? `Recent commits: ${recentCommits.join(' | ')}` : '',
|
|
90
|
+
]
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.join(' ');
|
|
93
|
+
return saveCheckpoint({
|
|
94
|
+
projectPath: projectRoot,
|
|
95
|
+
filesModified,
|
|
96
|
+
// Only the conversation knows these; an auto-capture must not fabricate them.
|
|
97
|
+
decisionsMade: [],
|
|
98
|
+
bugsResolved: [],
|
|
99
|
+
tasksPending: [],
|
|
100
|
+
summary: summary ? `${summary}\n\n${derived}` : derived,
|
|
101
|
+
}, projectRoot);
|
|
102
|
+
}
|
|
46
103
|
export function loadLatestCheckpoint(projectRoot) {
|
|
47
104
|
const files = listCheckpoints(projectRoot);
|
|
48
105
|
if (files.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationCheckpoint.js","sourceRoot":"","sources":["../../../src/utils/ConversationCheckpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationCheckpoint.js","sourceRoot":"","sources":["../../../src/utils/ConversationCheckpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
* The proxy exposes the ledger via GET /api/savings-breakdown for the dashboard to consume.
|
|
8
8
|
*/
|
|
9
9
|
export type SavingsSource = 'clipboard' | 'contextSqueeze' | 'historyPrune' | 'complexityRouting' | 'cache';
|
|
10
|
+
/**
|
|
11
|
+
* Where Lemma *spends* tokens. Without these the ledger is single-entry bookkeeping:
|
|
12
|
+
* it can only ever go up, which makes it useless as evidence that Lemma is net positive.
|
|
13
|
+
*
|
|
14
|
+
* - mcpInstructions: the TURBOMODE prompt + tool schemas injected into the model's
|
|
15
|
+
* system prompt. Charged once per session, but re-read on every request.
|
|
16
|
+
* - toolResult: bytes each tool result adds to the model's context.
|
|
17
|
+
* - cacheMiss: round-trip burned on a lookup that returned nothing.
|
|
18
|
+
*/
|
|
19
|
+
export type CostSource = 'mcpInstructions' | 'toolResult' | 'cacheMiss';
|
|
10
20
|
export interface SourceStats {
|
|
11
21
|
/** How many individual savings events were recorded */
|
|
12
22
|
events: number;
|
|
@@ -15,6 +25,22 @@ export interface SourceStats {
|
|
|
15
25
|
/** Estimated USD saved (tokensSaved * avg price per token) */
|
|
16
26
|
costSaved: number;
|
|
17
27
|
}
|
|
28
|
+
export interface CostStats {
|
|
29
|
+
/** How many individual cost events were recorded */
|
|
30
|
+
events: number;
|
|
31
|
+
/** Estimated tokens spent (chars / 4) */
|
|
32
|
+
tokensSpent: number;
|
|
33
|
+
/** Estimated USD spent (tokensSpent * avg price per token) */
|
|
34
|
+
costSpent: number;
|
|
35
|
+
}
|
|
36
|
+
export interface NetStats {
|
|
37
|
+
/** tokensSaved - tokensSpent. Negative means Lemma cost more than it saved. */
|
|
38
|
+
netTokens: number;
|
|
39
|
+
/** USD equivalent of netTokens. Negative means net loss. */
|
|
40
|
+
netCost: number;
|
|
41
|
+
/** tokensSaved / tokensSpent. Below 1.0 means Lemma is not paying for itself. */
|
|
42
|
+
ratio: number;
|
|
43
|
+
}
|
|
18
44
|
export interface SavingsSnapshot {
|
|
19
45
|
clipboard: SourceStats;
|
|
20
46
|
contextSqueeze: SourceStats;
|
|
@@ -22,10 +48,14 @@ export interface SavingsSnapshot {
|
|
|
22
48
|
complexityRouting: SourceStats;
|
|
23
49
|
cache: SourceStats;
|
|
24
50
|
total: SourceStats;
|
|
51
|
+
costs: Record<CostSource, CostStats>;
|
|
52
|
+
totalCost: CostStats;
|
|
53
|
+
net: NetStats;
|
|
25
54
|
sessionStartedAt: string;
|
|
26
55
|
}
|
|
27
56
|
declare class SavingsLedger {
|
|
28
57
|
private sources;
|
|
58
|
+
private costs;
|
|
29
59
|
private readonly sessionStartedAt;
|
|
30
60
|
constructor();
|
|
31
61
|
private load;
|
|
@@ -41,7 +71,14 @@ declare class SavingsLedger {
|
|
|
41
71
|
* Record a savings event directly in tokens (for sources that already know their token count).
|
|
42
72
|
*/
|
|
43
73
|
recordTokens(source: SavingsSource, tokensSaved: number): void;
|
|
44
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Record tokens Lemma *spent*. Counterpart to record()/recordTokens() — without
|
|
76
|
+
* this the ledger can only ever grow, which is not evidence of anything.
|
|
77
|
+
*/
|
|
78
|
+
recordCost(source: CostSource, tokensSpent: number): void;
|
|
79
|
+
/** Record a cost event by char count (converts with the same chars/4 heuristic). */
|
|
80
|
+
recordCostChars(source: CostSource, chars: number): void;
|
|
81
|
+
/** Returns a full snapshot including computed totals, costs and net position */
|
|
45
82
|
getSnapshot(): SavingsSnapshot;
|
|
46
83
|
/** Returns a pretty terminal summary block */
|
|
47
84
|
getTerminalSummary(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SavingsLedger.d.ts","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,cAAc,GAAG,mBAAmB,GAAG,OAAO,CAAC;AAE5G,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,cAAc,EAAE,WAAW,CAAC;IAC5B,YAAY,EAAE,WAAW,CAAC;IAC1B,iBAAiB,EAAE,WAAW,CAAC;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAQD,cAAM,aAAa;IACjB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;;
|
|
1
|
+
{"version":3,"file":"SavingsLedger.d.ts","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,cAAc,GAAG,mBAAmB,GAAG,OAAO,CAAC;AAE5G;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,YAAY,GAAG,WAAW,CAAC;AAExE,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,cAAc,EAAE,WAAW,CAAC;IAC5B,YAAY,EAAE,WAAW,CAAC;IAC1B,iBAAiB,EAAE,WAAW,CAAC;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,EAAE,QAAQ,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAQD,cAAM,aAAa;IACjB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;;IAmB1C,OAAO,CAAC,IAAI;IAwCZ,OAAO,CAAC,IAAI;IAeZ;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAa5E;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAS9D;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAQzD,oFAAoF;IACpF,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxD,gFAAgF;IAChF,WAAW,IAAI,eAAe;IAkC9B,8CAA8C;IAC9C,kBAAkB,IAAI,MAAM;IAoD5B,gDAAgD;IAChD,KAAK,IAAI,IAAI;CASd;AAED,gDAAgD;AAChD,eAAO,MAAM,aAAa,eAAsB,CAAC;AACjD,eAAe,aAAa,CAAC"}
|
|
@@ -22,6 +22,11 @@ class SavingsLedger {
|
|
|
22
22
|
complexityRouting: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
23
23
|
cache: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
24
24
|
};
|
|
25
|
+
this.costs = {
|
|
26
|
+
mcpInstructions: { events: 0, tokensSpent: 0, costSpent: 0 },
|
|
27
|
+
toolResult: { events: 0, tokensSpent: 0, costSpent: 0 },
|
|
28
|
+
cacheMiss: { events: 0, tokensSpent: 0, costSpent: 0 },
|
|
29
|
+
};
|
|
25
30
|
this.load();
|
|
26
31
|
}
|
|
27
32
|
load() {
|
|
@@ -43,6 +48,20 @@ class SavingsLedger {
|
|
|
43
48
|
};
|
|
44
49
|
}
|
|
45
50
|
}
|
|
51
|
+
// v2 adds the cost side under `_costs`. Ledgers written before v2 simply
|
|
52
|
+
// have no cost history — they load with zeroes rather than failing.
|
|
53
|
+
const parsedCosts = parsed._costs;
|
|
54
|
+
if (parsedCosts && typeof parsedCosts === 'object') {
|
|
55
|
+
for (const key of Object.keys(this.costs)) {
|
|
56
|
+
if (parsedCosts[key]) {
|
|
57
|
+
this.costs[key] = {
|
|
58
|
+
events: Number(parsedCosts[key].events || 0),
|
|
59
|
+
tokensSpent: Number(parsedCosts[key].tokensSpent || 0),
|
|
60
|
+
costSpent: Number(parsedCosts[key].costSpent || 0),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
46
65
|
}
|
|
47
66
|
}
|
|
48
67
|
}
|
|
@@ -56,7 +75,10 @@ class SavingsLedger {
|
|
|
56
75
|
if (!fs.existsSync(dir)) {
|
|
57
76
|
fs.mkdirSync(dir, { recursive: true });
|
|
58
77
|
}
|
|
59
|
-
|
|
78
|
+
// Savings stay at the top level so pre-v2 readers keep working; costs are
|
|
79
|
+
// additive under `_costs`.
|
|
80
|
+
const payload = { ...this.sources, _costs: this.costs, _version: 2 };
|
|
81
|
+
fs.writeFileSync(LEDGER_FILE, JSON.stringify(payload, null, 2), 'utf8');
|
|
60
82
|
}
|
|
61
83
|
catch (err) {
|
|
62
84
|
// Fail silently
|
|
@@ -91,7 +113,23 @@ class SavingsLedger {
|
|
|
91
113
|
this.sources[source].costSaved += costSaved;
|
|
92
114
|
this.save();
|
|
93
115
|
}
|
|
94
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* Record tokens Lemma *spent*. Counterpart to record()/recordTokens() — without
|
|
118
|
+
* this the ledger can only ever grow, which is not evidence of anything.
|
|
119
|
+
*/
|
|
120
|
+
recordCost(source, tokensSpent) {
|
|
121
|
+
if (tokensSpent <= 0)
|
|
122
|
+
return;
|
|
123
|
+
this.costs[source].events++;
|
|
124
|
+
this.costs[source].tokensSpent += tokensSpent;
|
|
125
|
+
this.costs[source].costSpent += tokensSpent * AVG_COST_PER_TOKEN;
|
|
126
|
+
this.save();
|
|
127
|
+
}
|
|
128
|
+
/** Record a cost event by char count (converts with the same chars/4 heuristic). */
|
|
129
|
+
recordCostChars(source, chars) {
|
|
130
|
+
this.recordCost(source, Math.floor(Math.max(0, chars) / 4));
|
|
131
|
+
}
|
|
132
|
+
/** Returns a full snapshot including computed totals, costs and net position */
|
|
95
133
|
getSnapshot() {
|
|
96
134
|
const total = { events: 0, tokensSaved: 0, costSaved: 0 };
|
|
97
135
|
for (const src of Object.values(this.sources)) {
|
|
@@ -99,9 +137,25 @@ class SavingsLedger {
|
|
|
99
137
|
total.tokensSaved += src.tokensSaved;
|
|
100
138
|
total.costSaved += src.costSaved;
|
|
101
139
|
}
|
|
140
|
+
const totalCost = { events: 0, tokensSpent: 0, costSpent: 0 };
|
|
141
|
+
for (const c of Object.values(this.costs)) {
|
|
142
|
+
totalCost.events += c.events;
|
|
143
|
+
totalCost.tokensSpent += c.tokensSpent;
|
|
144
|
+
totalCost.costSpent += c.costSpent;
|
|
145
|
+
}
|
|
146
|
+
const net = {
|
|
147
|
+
netTokens: total.tokensSaved - totalCost.tokensSpent,
|
|
148
|
+
netCost: total.costSaved - totalCost.costSpent,
|
|
149
|
+
ratio: totalCost.tokensSpent > 0
|
|
150
|
+
? total.tokensSaved / totalCost.tokensSpent
|
|
151
|
+
: (total.tokensSaved > 0 ? Infinity : 0),
|
|
152
|
+
};
|
|
102
153
|
return {
|
|
103
154
|
...this.sources,
|
|
104
155
|
total,
|
|
156
|
+
costs: { ...this.costs },
|
|
157
|
+
totalCost,
|
|
158
|
+
net,
|
|
105
159
|
sessionStartedAt: this.sessionStartedAt,
|
|
106
160
|
};
|
|
107
161
|
}
|
|
@@ -111,21 +165,40 @@ class SavingsLedger {
|
|
|
111
165
|
const fmt = (n) => n.toLocaleString('en-US');
|
|
112
166
|
const fmtUSD = (n) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 }).format(n);
|
|
113
167
|
const rows = [
|
|
114
|
-
['
|
|
115
|
-
['
|
|
116
|
-
['
|
|
117
|
-
['
|
|
118
|
-
['
|
|
168
|
+
['Clipboard Squeeze', snap.clipboard.tokensSaved, snap.clipboard.costSaved],
|
|
169
|
+
['Context Squeeze', snap.contextSqueeze.tokensSaved, snap.contextSqueeze.costSaved],
|
|
170
|
+
['History Prune', snap.historyPrune.tokensSaved, snap.historyPrune.costSaved],
|
|
171
|
+
['Model Routing', snap.complexityRouting.tokensSaved, snap.complexityRouting.costSaved],
|
|
172
|
+
['Semantic Cache', snap.cache.tokensSaved, snap.cache.costSaved],
|
|
173
|
+
];
|
|
174
|
+
const costRows = [
|
|
175
|
+
['MCP Instructions', snap.costs.mcpInstructions.tokensSpent, snap.costs.mcpInstructions.costSpent],
|
|
176
|
+
['Tool Results', snap.costs.toolResult.tokensSpent, snap.costs.toolResult.costSpent],
|
|
177
|
+
['Cache Misses', snap.costs.cacheMiss.tokensSpent, snap.costs.cacheMiss.costSpent],
|
|
119
178
|
];
|
|
179
|
+
const net = snap.net;
|
|
180
|
+
const ratioStr = net.ratio === Infinity
|
|
181
|
+
? 'n/a (no cost recorded)'
|
|
182
|
+
: `${net.ratio.toFixed(2)}x`;
|
|
183
|
+
// Every data row shares one template so the box stays aligned; labels are padded
|
|
184
|
+
// to a fixed width rather than hand-spaced per row.
|
|
185
|
+
const row = (label, tokens, cost) => `│ ${label.padEnd(22)}${fmt(tokens).padStart(9)} tokens ${fmtUSD(cost).padStart(11)} │`;
|
|
186
|
+
const text = (s) => `│ ${s.padEnd(52)}│`;
|
|
187
|
+
const rule = '│ ' + '─'.repeat(50) + ' │';
|
|
120
188
|
const lines = [
|
|
121
189
|
'┌──────────────────────────────────────────────────────┐',
|
|
122
|
-
'
|
|
190
|
+
text('💰 Lemma Ledger (this session)'),
|
|
123
191
|
'├──────────────────────────────────────────────────────┤',
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
192
|
+
text('SAVED'),
|
|
193
|
+
...rows.filter(([, t]) => t > 0).map(([l, t, c]) => row(l, t, c)),
|
|
194
|
+
row('subtotal', snap.total.tokensSaved, snap.total.costSaved),
|
|
195
|
+
rule,
|
|
196
|
+
text('SPENT'),
|
|
197
|
+
...costRows.filter(([, t]) => t > 0).map(([l, t, c]) => row(l, t, c)),
|
|
198
|
+
row('subtotal', snap.totalCost.tokensSpent, snap.totalCost.costSpent),
|
|
199
|
+
rule,
|
|
200
|
+
row(net.netTokens >= 0 ? 'NET SAVED' : 'NET COST', net.netTokens, net.netCost),
|
|
201
|
+
text(`ratio saved/spent: ${ratioStr}`),
|
|
129
202
|
'└──────────────────────────────────────────────────────┘',
|
|
130
203
|
];
|
|
131
204
|
return lines.join('\n');
|
|
@@ -135,6 +208,9 @@ class SavingsLedger {
|
|
|
135
208
|
for (const key of Object.keys(this.sources)) {
|
|
136
209
|
this.sources[key] = { events: 0, tokensSaved: 0, costSaved: 0 };
|
|
137
210
|
}
|
|
211
|
+
for (const key of Object.keys(this.costs)) {
|
|
212
|
+
this.costs[key] = { events: 0, tokensSpent: 0, costSpent: 0 };
|
|
213
|
+
}
|
|
138
214
|
this.save();
|
|
139
215
|
}
|
|
140
216
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SavingsLedger.js","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SavingsLedger.js","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestAutofixInterceptor.d.ts","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TestAutofixInterceptor.d.ts","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AA6ED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,YAAa,EAC5B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAmCnB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
+
import { getBrain, deriveProjectId } from '../subconscious/TheBrainV2';
|
|
2
3
|
function extractFailures(output) {
|
|
3
4
|
const failures = [];
|
|
4
5
|
// Jest/Vitest failure pattern
|
|
@@ -51,35 +52,23 @@ function extractTestCounts(output) {
|
|
|
51
52
|
}
|
|
52
53
|
return { total, passed, failed };
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Looks for a previously stored fix for a test failure.
|
|
57
|
+
*
|
|
58
|
+
* Previously scanned `<project>/.lemma/memory/*.json` — a directory no code path writes —
|
|
59
|
+
* so `brainHit` was always false and the "Brain-suggested fix" feature never fired once.
|
|
60
|
+
* Now it asks the Brain directly, which also replaces the hand-rolled token overlap score
|
|
61
|
+
* with the BM25 ranking the Brain already implements.
|
|
62
|
+
*/
|
|
54
63
|
function searchBrainForFix(errorMessage, projectRoot) {
|
|
55
64
|
try {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
const results = getBrain().search(errorMessage, 1, 0.35, {
|
|
66
|
+
projectId: deriveProjectId(projectRoot),
|
|
67
|
+
});
|
|
68
|
+
const top = results[0];
|
|
69
|
+
if (!top)
|
|
60
70
|
return { fix: null, hit: false };
|
|
61
|
-
|
|
62
|
-
const files = fs.readdirSync(brainDir).filter((f) => f.endsWith('.json'));
|
|
63
|
-
let bestScore = 0;
|
|
64
|
-
let bestFix = null;
|
|
65
|
-
for (const f of files) {
|
|
66
|
-
try {
|
|
67
|
-
const data = JSON.parse(fs.readFileSync(path.join(brainDir, f), 'utf8'));
|
|
68
|
-
const content = `${data.query || ''} ${data.response || ''}`.toLowerCase();
|
|
69
|
-
let score = 0;
|
|
70
|
-
for (const token of errorTokens) {
|
|
71
|
-
if (content.includes(token))
|
|
72
|
-
score++;
|
|
73
|
-
}
|
|
74
|
-
const normalizedScore = errorTokens.length > 0 ? score / errorTokens.length : 0;
|
|
75
|
-
if (normalizedScore > bestScore && normalizedScore > 0.3) {
|
|
76
|
-
bestScore = normalizedScore;
|
|
77
|
-
bestFix = String(data.response).slice(0, 500);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
catch { }
|
|
81
|
-
}
|
|
82
|
-
return { fix: bestFix, hit: bestScore > 0.3 };
|
|
71
|
+
return { fix: String(top.response).slice(0, 500), hit: true };
|
|
83
72
|
}
|
|
84
73
|
catch {
|
|
85
74
|
return { fix: null, hit: false };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestAutofixInterceptor.js","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"TestAutofixInterceptor.js","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,5 +26,20 @@ type ReportPayload = ReportByChars | ReportByTokens;
|
|
|
26
26
|
* Fire-and-forget — never throws, never blocks.
|
|
27
27
|
*/
|
|
28
28
|
export declare function reportSavings(payload: ReportPayload): void;
|
|
29
|
+
type CostSource = 'mcpInstructions' | 'toolResult' | 'cacheMiss';
|
|
30
|
+
interface CostPayload {
|
|
31
|
+
source: CostSource;
|
|
32
|
+
/** Tokens spent. Use this or `chars`, not both. */
|
|
33
|
+
tokens?: number;
|
|
34
|
+
/** Chars spent — converted with the same chars/4 heuristic as savings. */
|
|
35
|
+
chars?: number;
|
|
36
|
+
toolName?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Report tokens Lemma *spent* to the proxy's ledger. Same fire-and-forget contract
|
|
40
|
+
* as reportSavings — the cost side must never be able to break a tool call, but it
|
|
41
|
+
* also must not be silently skipped, or the ledger goes back to only counting wins.
|
|
42
|
+
*/
|
|
43
|
+
export declare function reportCost(payload: CostPayload): void;
|
|
29
44
|
export {};
|
|
30
45
|
//# sourceMappingURL=reportSavings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportSavings.d.ts","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,cAAc,GAAG,mBAAmB,GAAG,OAAO,CAAC;AAErG,UAAU,aAAa;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC;AAYpD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"reportSavings.d.ts","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,cAAc,GAAG,mBAAmB,GAAG,OAAO,CAAC;AAErG,UAAU,aAAa;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC;AAYpD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAE1D;AAED,KAAK,UAAU,GAAG,iBAAiB,GAAG,YAAY,GAAG,WAAW,CAAC;AAEjE,UAAU,WAAW;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAErD"}
|
|
@@ -23,13 +23,24 @@ function getProxyPort() {
|
|
|
23
23
|
* Fire-and-forget — never throws, never blocks.
|
|
24
24
|
*/
|
|
25
25
|
export function reportSavings(payload) {
|
|
26
|
+
post('/api/savings-record', payload);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Report tokens Lemma *spent* to the proxy's ledger. Same fire-and-forget contract
|
|
30
|
+
* as reportSavings — the cost side must never be able to break a tool call, but it
|
|
31
|
+
* also must not be silently skipped, or the ledger goes back to only counting wins.
|
|
32
|
+
*/
|
|
33
|
+
export function reportCost(payload) {
|
|
34
|
+
post('/api/cost-record', payload);
|
|
35
|
+
}
|
|
36
|
+
function post(pathname, payload) {
|
|
26
37
|
try {
|
|
27
38
|
const port = getProxyPort();
|
|
28
39
|
const body = JSON.stringify(payload);
|
|
29
40
|
const req = http.request({
|
|
30
41
|
hostname: '127.0.0.1',
|
|
31
42
|
port: parseInt(port),
|
|
32
|
-
path:
|
|
43
|
+
path: pathname,
|
|
33
44
|
method: 'POST',
|
|
34
45
|
headers: {
|
|
35
46
|
'Content-Type': 'application/json',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportSavings.js","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAuBxB,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,yBAAyB,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAsB;IAClD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;YACvB,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;YACpB,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"reportSavings.js","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAuBxB,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,yBAAyB,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAsB;IAClD,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAaD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,IAAI,CAAC,QAAgB,EAAE,OAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;YACvB,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;YACpB,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;aAC1C;SACF,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,yCAAyC;QACpE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxuss/lemma",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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",
|
|
7
7
|
"types": "./dist/esm/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
9
|
"lemma": "lemma-proxy.cjs",
|
|
10
|
-
"lemma-mcp-server": "mcp-server.js"
|
|
10
|
+
"lemma-mcp-server": "mcp-server.js",
|
|
11
|
+
"lemma-checkpoint": "bin/checkpoint.js"
|
|
11
12
|
},
|
|
12
13
|
"exports": {
|
|
13
14
|
".": {
|
|
@@ -88,6 +89,7 @@
|
|
|
88
89
|
"cache-proxy.js",
|
|
89
90
|
"bin/init.js",
|
|
90
91
|
"bin/cli.js",
|
|
92
|
+
"bin/checkpoint.js",
|
|
91
93
|
"dashboard/dist/**/*",
|
|
92
94
|
"!dist/examples/**",
|
|
93
95
|
"README.md",
|