@nxuss/lemma 0.5.1 → 0.5.3
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 +1 -1
- package/dashboard/dist/assets/{index-B4TA31pA.js → index-CIlkFwDs.js} +98 -98
- package/dashboard/dist/assets/index-CIlkFwDs.js.map +1 -0
- package/dashboard/dist/index.html +1 -1
- package/dist/cjs/cli/lemma-proxy.d.ts +2 -0
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +416 -121
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/config/index.d.ts.map +1 -1
- package/dist/cjs/config/index.js +2 -1
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/errors/LemmaError.d.ts +52 -0
- package/dist/cjs/errors/LemmaError.d.ts.map +1 -0
- package/dist/cjs/errors/LemmaError.js +84 -0
- package/dist/cjs/errors/LemmaError.js.map +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +24 -22
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/mcp/index.js +81 -0
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/subconscious/SemanticCache.d.ts +4 -4
- package/dist/cjs/subconscious/SemanticCache.d.ts.map +1 -1
- package/dist/cjs/subconscious/SemanticCache.js +14 -10
- package/dist/cjs/subconscious/SemanticCache.js.map +1 -1
- package/dist/cjs/types/index.d.ts +8 -8
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/utils/ClipboardWatcher.d.ts.map +1 -1
- package/dist/cjs/utils/ClipboardWatcher.js +3 -0
- package/dist/cjs/utils/ClipboardWatcher.js.map +1 -1
- package/dist/cjs/utils/SavingsLedger.d.ts +52 -0
- package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -0
- package/dist/cjs/utils/SavingsLedger.js +101 -0
- package/dist/cjs/utils/SavingsLedger.js.map +1 -0
- package/dist/cjs/utils/logger.d.ts +27 -6
- package/dist/cjs/utils/logger.d.ts.map +1 -1
- package/dist/cjs/utils/logger.js +96 -28
- package/dist/cjs/utils/logger.js.map +1 -1
- package/dist/cjs/utils/reportSavings.d.ts +24 -0
- package/dist/cjs/utils/reportSavings.d.ts.map +1 -0
- package/dist/cjs/utils/reportSavings.js +53 -0
- package/dist/cjs/utils/reportSavings.js.map +1 -0
- package/dist/esm/cli/lemma-proxy.d.ts +2 -0
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +414 -121
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/config/index.d.ts.map +1 -1
- package/dist/esm/config/index.js +2 -1
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/errors/LemmaError.d.ts +52 -0
- package/dist/esm/errors/LemmaError.d.ts.map +1 -0
- package/dist/esm/errors/LemmaError.js +75 -0
- package/dist/esm/errors/LemmaError.js.map +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +24 -22
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mcp/index.js +81 -0
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/subconscious/SemanticCache.d.ts +4 -4
- package/dist/esm/subconscious/SemanticCache.d.ts.map +1 -1
- package/dist/esm/subconscious/SemanticCache.js +14 -10
- package/dist/esm/subconscious/SemanticCache.js.map +1 -1
- package/dist/esm/types/index.d.ts +8 -8
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/utils/ClipboardWatcher.d.ts.map +1 -1
- package/dist/esm/utils/ClipboardWatcher.js +3 -0
- package/dist/esm/utils/ClipboardWatcher.js.map +1 -1
- package/dist/esm/utils/SavingsLedger.d.ts +52 -0
- package/dist/esm/utils/SavingsLedger.d.ts.map +1 -0
- package/dist/esm/utils/SavingsLedger.js +98 -0
- package/dist/esm/utils/SavingsLedger.js.map +1 -0
- package/dist/esm/utils/logger.d.ts +27 -6
- package/dist/esm/utils/logger.d.ts.map +1 -1
- package/dist/esm/utils/logger.js +93 -28
- package/dist/esm/utils/logger.js.map +1 -1
- package/dist/esm/utils/reportSavings.d.ts +24 -0
- package/dist/esm/utils/reportSavings.d.ts.map +1 -0
- package/dist/esm/utils/reportSavings.js +47 -0
- package/dist/esm/utils/reportSavings.js.map +1 -0
- package/package.json +27 -24
- package/dashboard/dist/assets/index-B4TA31pA.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SavingsLedger — Singleton accumulator for token savings across all Lemma modules.
|
|
3
|
+
*
|
|
4
|
+
* Every module (ClipboardWatcher, ContextSqueezer, ComplexityRouter, SemanticCache)
|
|
5
|
+
* calls `ledger.record(source, charsBefore, charsAfter)` — no one knows about the dashboard.
|
|
6
|
+
*
|
|
7
|
+
* The proxy exposes the ledger via GET /api/savings-breakdown for the dashboard to consume.
|
|
8
|
+
*/
|
|
9
|
+
export type SavingsSource = 'clipboard' | 'contextSqueeze' | 'historyPrune' | 'complexityRouting' | 'cache';
|
|
10
|
+
export interface SourceStats {
|
|
11
|
+
/** How many individual savings events were recorded */
|
|
12
|
+
events: number;
|
|
13
|
+
/** Estimated tokens saved (chars / 4) */
|
|
14
|
+
tokensSaved: number;
|
|
15
|
+
/** Estimated USD saved (tokensSaved * avg price per token) */
|
|
16
|
+
costSaved: number;
|
|
17
|
+
}
|
|
18
|
+
export interface SavingsSnapshot {
|
|
19
|
+
clipboard: SourceStats;
|
|
20
|
+
contextSqueeze: SourceStats;
|
|
21
|
+
historyPrune: SourceStats;
|
|
22
|
+
complexityRouting: SourceStats;
|
|
23
|
+
cache: SourceStats;
|
|
24
|
+
total: SourceStats;
|
|
25
|
+
sessionStartedAt: string;
|
|
26
|
+
}
|
|
27
|
+
declare class SavingsLedger {
|
|
28
|
+
private sources;
|
|
29
|
+
private readonly sessionStartedAt;
|
|
30
|
+
constructor();
|
|
31
|
+
/**
|
|
32
|
+
* Record a savings event by char counts (automatically converts to token estimate).
|
|
33
|
+
* @param source Which module recorded the savings
|
|
34
|
+
* @param charsBefore Original char count before compression/routing
|
|
35
|
+
* @param charsAfter Resulting char count after compression/routing
|
|
36
|
+
*/
|
|
37
|
+
record(source: SavingsSource, charsBefore: number, charsAfter: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Record a savings event directly in tokens (for sources that already know their token count).
|
|
40
|
+
*/
|
|
41
|
+
recordTokens(source: SavingsSource, tokensSaved: number): void;
|
|
42
|
+
/** Returns a full snapshot including computed totals */
|
|
43
|
+
getSnapshot(): SavingsSnapshot;
|
|
44
|
+
/** Returns a pretty terminal summary block */
|
|
45
|
+
getTerminalSummary(): string;
|
|
46
|
+
/** Reset all counters (e.g., on cache clear) */
|
|
47
|
+
reset(): void;
|
|
48
|
+
}
|
|
49
|
+
/** Global singleton — import this everywhere */
|
|
50
|
+
export declare const savingsLedger: SavingsLedger;
|
|
51
|
+
export default savingsLedger;
|
|
52
|
+
//# sourceMappingURL=SavingsLedger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SavingsLedger.d.ts","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,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;AAKD,cAAM,aAAa;IACjB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;;IAa1C;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAY5E;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAQ9D,wDAAwD;IACxD,WAAW,IAAI,eAAe;IAgB9B,8CAA8C;IAC9C,kBAAkB,IAAI,MAAM;IA+B5B,gDAAgD;IAChD,KAAK,IAAI,IAAI;CAKd;AAED,gDAAgD;AAChD,eAAO,MAAM,aAAa,eAAsB,CAAC;AACjD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SavingsLedger — Singleton accumulator for token savings across all Lemma modules.
|
|
4
|
+
*
|
|
5
|
+
* Every module (ClipboardWatcher, ContextSqueezer, ComplexityRouter, SemanticCache)
|
|
6
|
+
* calls `ledger.record(source, charsBefore, charsAfter)` — no one knows about the dashboard.
|
|
7
|
+
*
|
|
8
|
+
* The proxy exposes the ledger via GET /api/savings-breakdown for the dashboard to consume.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.savingsLedger = void 0;
|
|
12
|
+
/** Average blended cost per input token across GPT-4o / Claude Sonnet / Gemini Pro */
|
|
13
|
+
const AVG_COST_PER_TOKEN = 0.000008; // $0.008 per 1K tokens
|
|
14
|
+
class SavingsLedger {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.sessionStartedAt = new Date().toISOString();
|
|
17
|
+
this.sources = {
|
|
18
|
+
clipboard: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
19
|
+
contextSqueeze: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
20
|
+
historyPrune: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
21
|
+
complexityRouting: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
22
|
+
cache: { events: 0, tokensSaved: 0, costSaved: 0 },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Record a savings event by char counts (automatically converts to token estimate).
|
|
27
|
+
* @param source Which module recorded the savings
|
|
28
|
+
* @param charsBefore Original char count before compression/routing
|
|
29
|
+
* @param charsAfter Resulting char count after compression/routing
|
|
30
|
+
*/
|
|
31
|
+
record(source, charsBefore, charsAfter) {
|
|
32
|
+
const charsSaved = Math.max(0, charsBefore - charsAfter);
|
|
33
|
+
if (charsSaved === 0)
|
|
34
|
+
return;
|
|
35
|
+
const tokensSaved = Math.floor(charsSaved / 4);
|
|
36
|
+
const costSaved = tokensSaved * AVG_COST_PER_TOKEN;
|
|
37
|
+
this.sources[source].events++;
|
|
38
|
+
this.sources[source].tokensSaved += tokensSaved;
|
|
39
|
+
this.sources[source].costSaved += costSaved;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Record a savings event directly in tokens (for sources that already know their token count).
|
|
43
|
+
*/
|
|
44
|
+
recordTokens(source, tokensSaved) {
|
|
45
|
+
if (tokensSaved <= 0)
|
|
46
|
+
return;
|
|
47
|
+
const costSaved = tokensSaved * AVG_COST_PER_TOKEN;
|
|
48
|
+
this.sources[source].events++;
|
|
49
|
+
this.sources[source].tokensSaved += tokensSaved;
|
|
50
|
+
this.sources[source].costSaved += costSaved;
|
|
51
|
+
}
|
|
52
|
+
/** Returns a full snapshot including computed totals */
|
|
53
|
+
getSnapshot() {
|
|
54
|
+
const total = { events: 0, tokensSaved: 0, costSaved: 0 };
|
|
55
|
+
for (const src of Object.values(this.sources)) {
|
|
56
|
+
total.events += src.events;
|
|
57
|
+
total.tokensSaved += src.tokensSaved;
|
|
58
|
+
total.costSaved += src.costSaved;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
...this.sources,
|
|
62
|
+
total,
|
|
63
|
+
sessionStartedAt: this.sessionStartedAt,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Returns a pretty terminal summary block */
|
|
67
|
+
getTerminalSummary() {
|
|
68
|
+
const snap = this.getSnapshot();
|
|
69
|
+
const fmt = (n) => n.toLocaleString('en-US');
|
|
70
|
+
const fmtUSD = (n) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 }).format(n);
|
|
71
|
+
const rows = [
|
|
72
|
+
['📋 Clipboard Squeeze', snap.clipboard.tokensSaved, snap.clipboard.costSaved],
|
|
73
|
+
['🗜️ Context Squeeze ', snap.contextSqueeze.tokensSaved, snap.contextSqueeze.costSaved],
|
|
74
|
+
['📜 History Prune ', snap.historyPrune.tokensSaved, snap.historyPrune.costSaved],
|
|
75
|
+
['🔀 Model Routing ', snap.complexityRouting.tokensSaved, snap.complexityRouting.costSaved],
|
|
76
|
+
['⚡ Semantic Cache ', snap.cache.tokensSaved, snap.cache.costSaved],
|
|
77
|
+
];
|
|
78
|
+
const lines = [
|
|
79
|
+
'┌──────────────────────────────────────────────────────┐',
|
|
80
|
+
'│ 💰 Lemma Savings Report (this session) │',
|
|
81
|
+
'├──────────────────────────────────────────────────────┤',
|
|
82
|
+
...rows
|
|
83
|
+
.filter(([, tokens]) => tokens > 0)
|
|
84
|
+
.map(([label, tokens, cost]) => `│ ${label} ${fmt(tokens).padStart(7)} tokens ${fmtUSD(cost).padStart(10)} │`),
|
|
85
|
+
'│ ────────────────────────────────────────────────── │',
|
|
86
|
+
`│ TOTAL ${fmt(snap.total.tokensSaved).padStart(7)} tokens ${fmtUSD(snap.total.costSaved).padStart(10)} │`,
|
|
87
|
+
'└──────────────────────────────────────────────────────┘',
|
|
88
|
+
];
|
|
89
|
+
return lines.join('\n');
|
|
90
|
+
}
|
|
91
|
+
/** Reset all counters (e.g., on cache clear) */
|
|
92
|
+
reset() {
|
|
93
|
+
for (const key of Object.keys(this.sources)) {
|
|
94
|
+
this.sources[key] = { events: 0, tokensSaved: 0, costSaved: 0 };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Global singleton — import this everywhere */
|
|
99
|
+
exports.savingsLedger = new SavingsLedger();
|
|
100
|
+
exports.default = exports.savingsLedger;
|
|
101
|
+
//# sourceMappingURL=SavingsLedger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SavingsLedger.js","sourceRoot":"","sources":["../../../src/utils/SavingsLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,24 +8,45 @@ export declare enum LogLevel {
|
|
|
8
8
|
DEBUG = 3
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Structured Logger Entry Schema
|
|
12
|
+
*/
|
|
13
|
+
export interface LogEntry {
|
|
14
|
+
timestamp: string;
|
|
15
|
+
level: string;
|
|
16
|
+
context: string;
|
|
17
|
+
message: string;
|
|
18
|
+
meta?: any;
|
|
19
|
+
error?: {
|
|
20
|
+
message: string;
|
|
21
|
+
stack?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Enterprise Structured Logger supporting standard console and file output streams.
|
|
12
26
|
*/
|
|
13
27
|
declare class Logger {
|
|
14
28
|
private level;
|
|
15
29
|
private context;
|
|
30
|
+
private format;
|
|
31
|
+
private logFilePath;
|
|
32
|
+
private disableConsole;
|
|
16
33
|
constructor(context?: string);
|
|
17
34
|
/**
|
|
18
35
|
* Parse log level from string
|
|
19
36
|
*/
|
|
20
37
|
private parseLogLevel;
|
|
21
38
|
/**
|
|
22
|
-
* Format
|
|
39
|
+
* Format text log line with color
|
|
23
40
|
*/
|
|
24
|
-
private
|
|
41
|
+
private formatText;
|
|
25
42
|
/**
|
|
26
|
-
*
|
|
43
|
+
* Safe file appending utility
|
|
27
44
|
*/
|
|
28
|
-
private
|
|
45
|
+
private appendToFile;
|
|
46
|
+
/**
|
|
47
|
+
* Unified writer for standard and file streams
|
|
48
|
+
*/
|
|
49
|
+
private log;
|
|
29
50
|
/**
|
|
30
51
|
* Log error message
|
|
31
52
|
*/
|
|
@@ -47,7 +68,7 @@ declare class Logger {
|
|
|
47
68
|
*/
|
|
48
69
|
metric(name: string, value: number, unit?: string): void;
|
|
49
70
|
/**
|
|
50
|
-
* Create child logger with
|
|
71
|
+
* Create child logger with parent context chaining
|
|
51
72
|
*/
|
|
52
73
|
child(context: string): Logger;
|
|
53
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAcD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,cAAM,MAAM;IACV,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAkB;gBAE5B,OAAO,GAAE,MAAc;IAsBnC;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,GAAG;IAkDX;;OAEG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,IAAI;IAIxD;;OAEG;IACI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAI9C;;OAEG;IACI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAI9C;;OAEG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAI/C;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAa,GAAG,IAAI;IAKrE;;OAEG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAGtC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAc,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,QAAqC,CAAC"}
|
package/dist/cjs/utils/logger.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.logger = exports.LogLevel = void 0;
|
|
4
7
|
exports.createLogger = createLogger;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
5
10
|
const config_1 = require("../config");
|
|
6
11
|
/**
|
|
7
12
|
* Log levels
|
|
@@ -25,12 +30,29 @@ const colors = {
|
|
|
25
30
|
gray: '\x1b[90m',
|
|
26
31
|
};
|
|
27
32
|
/**
|
|
28
|
-
*
|
|
33
|
+
* Enterprise Structured Logger supporting standard console and file output streams.
|
|
29
34
|
*/
|
|
30
35
|
class Logger {
|
|
31
36
|
constructor(context = 'App') {
|
|
37
|
+
this.logFilePath = null;
|
|
38
|
+
this.disableConsole = false;
|
|
32
39
|
this.context = context;
|
|
33
|
-
|
|
40
|
+
// Resolve runtime settings dynamically
|
|
41
|
+
const rawLevel = process.env.LEMMA_LOG_LEVEL || process.env.LOG_LEVEL || config_1.config?.logLevel || 'info';
|
|
42
|
+
this.level = this.parseLogLevel(rawLevel);
|
|
43
|
+
this.format = (process.env.LEMMA_LOG_FORMAT || process.env.LOG_FORMAT || 'text').toLowerCase() === 'json' ? 'json' : 'text';
|
|
44
|
+
this.logFilePath = process.env.LEMMA_LOG_FILE || process.env.LOG_FILE || null;
|
|
45
|
+
this.disableConsole = (process.env.LEMMA_LOG_DISABLE_CONSOLE || 'false').toLowerCase() === 'true';
|
|
46
|
+
// Proactively construct base directory for log files if specified
|
|
47
|
+
if (this.logFilePath) {
|
|
48
|
+
try {
|
|
49
|
+
const dir = path_1.default.dirname(path_1.default.resolve(this.logFilePath));
|
|
50
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
51
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
}
|
|
34
56
|
}
|
|
35
57
|
/**
|
|
36
58
|
* Parse log level from string
|
|
@@ -50,64 +72,110 @@ class Logger {
|
|
|
50
72
|
}
|
|
51
73
|
}
|
|
52
74
|
/**
|
|
53
|
-
* Format
|
|
75
|
+
* Format text log line with color
|
|
54
76
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
77
|
+
formatText(level, message, metaStr, colorCode) {
|
|
78
|
+
const timestamp = new Date().toISOString();
|
|
79
|
+
return `${colorCode}[${timestamp}] [${level}] [${this.context}] ${message}${metaStr}${colors.reset}`;
|
|
57
80
|
}
|
|
58
81
|
/**
|
|
59
|
-
*
|
|
82
|
+
* Safe file appending utility
|
|
60
83
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
appendToFile(entry) {
|
|
85
|
+
if (!this.logFilePath)
|
|
86
|
+
return;
|
|
87
|
+
try {
|
|
88
|
+
const line = this.format === 'json'
|
|
89
|
+
? JSON.stringify(entry)
|
|
90
|
+
: `[${entry.timestamp}] [${entry.level}] [${entry.context}] ${entry.message}${entry.meta ? ' ' + JSON.stringify(entry.meta) : ''}${entry.error ? ' error: ' + entry.error.message + '\n' + (entry.error.stack || '') : ''}`;
|
|
91
|
+
fs_1.default.appendFileSync(this.logFilePath, line + '\n', 'utf8');
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Unified writer for standard and file streams
|
|
97
|
+
*/
|
|
98
|
+
log(levelStr, levelVal, message, colorCode, meta, errObj) {
|
|
99
|
+
if (levelVal > this.level)
|
|
100
|
+
return;
|
|
101
|
+
const timestamp = new Date().toISOString();
|
|
102
|
+
const entry = {
|
|
103
|
+
timestamp,
|
|
104
|
+
level: levelStr,
|
|
105
|
+
context: this.context,
|
|
106
|
+
message,
|
|
107
|
+
};
|
|
108
|
+
if (meta !== undefined) {
|
|
109
|
+
entry.meta = meta;
|
|
110
|
+
}
|
|
111
|
+
if (errObj) {
|
|
112
|
+
entry.error = {
|
|
113
|
+
message: errObj instanceof Error ? errObj.message : String(errObj),
|
|
114
|
+
stack: errObj instanceof Error ? errObj.stack : undefined,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Output to Console
|
|
118
|
+
if (!this.disableConsole) {
|
|
119
|
+
if (this.format === 'json') {
|
|
120
|
+
const jsonLine = JSON.stringify(entry);
|
|
121
|
+
if (levelVal === LogLevel.ERROR) {
|
|
122
|
+
console.error(jsonLine);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.log(jsonLine);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
|
|
130
|
+
const colorLine = this.formatText(levelStr, message, metaStr, colorCode);
|
|
131
|
+
if (levelVal === LogLevel.ERROR) {
|
|
132
|
+
console.error(colorLine);
|
|
133
|
+
if (errObj && errObj.stack) {
|
|
134
|
+
console.error(`${colors.red}${errObj.stack}${colors.reset}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.log(colorLine);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Write to File Sink
|
|
143
|
+
this.appendToFile(entry);
|
|
65
144
|
}
|
|
66
145
|
/**
|
|
67
146
|
* Log error message
|
|
68
147
|
*/
|
|
69
148
|
error(message, error) {
|
|
70
|
-
|
|
71
|
-
return;
|
|
72
|
-
const meta = error instanceof Error
|
|
73
|
-
? { error: error.message, stack: error.stack }
|
|
74
|
-
: error;
|
|
75
|
-
console.error(`${colors.red}${this.format('ERROR', message, meta)}${colors.reset}`);
|
|
149
|
+
this.log('ERROR', LogLevel.ERROR, message, colors.red, undefined, error);
|
|
76
150
|
}
|
|
77
151
|
/**
|
|
78
152
|
* Log warning message
|
|
79
153
|
*/
|
|
80
154
|
warn(message, meta) {
|
|
81
|
-
|
|
82
|
-
return;
|
|
83
|
-
console.warn(`${colors.yellow}${this.format('WARN', message, meta)}${colors.reset}`);
|
|
155
|
+
this.log('WARN', LogLevel.WARN, message, colors.yellow, meta);
|
|
84
156
|
}
|
|
85
157
|
/**
|
|
86
158
|
* Log info message
|
|
87
159
|
*/
|
|
88
160
|
info(message, meta) {
|
|
89
|
-
|
|
90
|
-
return;
|
|
91
|
-
console.log(`${colors.blue}${this.format('INFO', message, meta)}${colors.reset}`);
|
|
161
|
+
this.log('INFO', LogLevel.INFO, message, colors.blue, meta);
|
|
92
162
|
}
|
|
93
163
|
/**
|
|
94
164
|
* Log debug message
|
|
95
165
|
*/
|
|
96
166
|
debug(message, meta) {
|
|
97
|
-
|
|
98
|
-
return;
|
|
99
|
-
console.log(`${colors.gray}${this.format('DEBUG', message, meta)}${colors.reset}`);
|
|
167
|
+
this.log('DEBUG', LogLevel.DEBUG, message, colors.gray, meta);
|
|
100
168
|
}
|
|
101
169
|
/**
|
|
102
170
|
* Log performance metric
|
|
103
171
|
*/
|
|
104
172
|
metric(name, value, unit = 'ms') {
|
|
105
|
-
if (
|
|
173
|
+
if (LogLevel.INFO > this.level)
|
|
106
174
|
return;
|
|
107
|
-
|
|
175
|
+
this.log('METRIC', LogLevel.INFO, `${name}: ${value}${unit}`, colors.cyan);
|
|
108
176
|
}
|
|
109
177
|
/**
|
|
110
|
-
* Create child logger with
|
|
178
|
+
* Create child logger with parent context chaining
|
|
111
179
|
*/
|
|
112
180
|
child(context) {
|
|
113
181
|
return new Logger(`${this.context}:${context}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reportSavings — Fire-and-forget helper to report token savings to the proxy's SavingsLedger.
|
|
3
|
+
*
|
|
4
|
+
* Used by processes that run separately from the proxy (e.g., MCP server, CLI tools).
|
|
5
|
+
* The proxy accumulates all savings in its in-memory SavingsLedger and serves them to the dashboard.
|
|
6
|
+
*/
|
|
7
|
+
type SavingsSource = 'clipboard' | 'contextSqueeze' | 'historyPrune' | 'complexityRouting' | 'cache';
|
|
8
|
+
interface ReportByChars {
|
|
9
|
+
source: SavingsSource;
|
|
10
|
+
charsBefore: number;
|
|
11
|
+
charsAfter: number;
|
|
12
|
+
}
|
|
13
|
+
interface ReportByTokens {
|
|
14
|
+
source: SavingsSource;
|
|
15
|
+
tokens: number;
|
|
16
|
+
}
|
|
17
|
+
type ReportPayload = ReportByChars | ReportByTokens;
|
|
18
|
+
/**
|
|
19
|
+
* Report savings to the proxy's SavingsLedger via HTTP POST.
|
|
20
|
+
* Fire-and-forget — never throws, never blocks.
|
|
21
|
+
*/
|
|
22
|
+
export declare function reportSavings(payload: ReportPayload): void;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=reportSavings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reportSavings.d.ts","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,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;CACpB;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC;AAapD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAsB1D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* reportSavings — Fire-and-forget helper to report token savings to the proxy's SavingsLedger.
|
|
4
|
+
*
|
|
5
|
+
* Used by processes that run separately from the proxy (e.g., MCP server, CLI tools).
|
|
6
|
+
* The proxy accumulates all savings in its in-memory SavingsLedger and serves them to the dashboard.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.reportSavings = reportSavings;
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const http_1 = __importDefault(require("http"));
|
|
16
|
+
function getProxyPort() {
|
|
17
|
+
try {
|
|
18
|
+
const HOME = process.env.HOME || process.env.USERPROFILE || '~';
|
|
19
|
+
const portFile = path_1.default.join(HOME, '.lemma-cache/proxy.port');
|
|
20
|
+
if (fs_1.default.existsSync(portFile)) {
|
|
21
|
+
return fs_1.default.readFileSync(portFile, 'utf8').trim();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
return '8081';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Report savings to the proxy's SavingsLedger via HTTP POST.
|
|
29
|
+
* Fire-and-forget — never throws, never blocks.
|
|
30
|
+
*/
|
|
31
|
+
function reportSavings(payload) {
|
|
32
|
+
try {
|
|
33
|
+
const port = getProxyPort();
|
|
34
|
+
const body = JSON.stringify(payload);
|
|
35
|
+
const req = http_1.default.request({
|
|
36
|
+
hostname: '127.0.0.1',
|
|
37
|
+
port: parseInt(port),
|
|
38
|
+
path: '/api/savings-record',
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
'Content-Length': Buffer.byteLength(body),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
req.on('error', () => { }); // Silently ignore if proxy isn't running
|
|
46
|
+
req.write(body);
|
|
47
|
+
req.end();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Never throw — savings reporting is non-critical
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=reportSavings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reportSavings.js","sourceRoot":"","sources":["../../../src/utils/reportSavings.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;AAoCH,sCAsBC;AAxDD,4CAAoB;AACpB,gDAAwB;AACxB,gDAAwB;AAiBxB,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC;QAChE,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;QAC5D,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,YAAE,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,SAAgB,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,cAAI,CAAC,OAAO,CAAC;YACvB,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;YACpB,IAAI,EAAE,qBAAqB;YAC3B,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AA8NA,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CA0I3D;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAyCtD;AAuxCD,wBAAsB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6KhL"}
|