@nxuss/lemma 0.9.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +18 -3
  2. package/bin/cli.js +97 -0
  3. package/bin/init.js +307 -0
  4. package/cache-proxy.js +191 -0
  5. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  6. package/dist/cjs/cli/lemma-proxy.js +2 -4
  7. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  8. package/dist/cjs/mcp/index.js +1 -1
  9. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  10. package/dist/cjs/mcp/tools.js +292 -71
  11. package/dist/cjs/mcp/tools.js.map +1 -1
  12. package/dist/cjs/subconscious/TheBrainV2.d.ts +102 -0
  13. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -0
  14. package/dist/cjs/subconscious/TheBrainV2.js +444 -0
  15. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -0
  16. package/dist/cjs/utils/ContextCollapser.d.ts +21 -0
  17. package/dist/cjs/utils/ContextCollapser.d.ts.map +1 -0
  18. package/dist/cjs/utils/ContextCollapser.js +132 -0
  19. package/dist/cjs/utils/ContextCollapser.js.map +1 -0
  20. package/dist/cjs/utils/ExecutiveReport.d.ts +29 -0
  21. package/dist/cjs/utils/ExecutiveReport.d.ts.map +1 -0
  22. package/dist/cjs/utils/ExecutiveReport.js +111 -0
  23. package/dist/cjs/utils/ExecutiveReport.js.map +1 -0
  24. package/dist/cjs/utils/SurgicalASTInsert.d.ts +21 -0
  25. package/dist/cjs/utils/SurgicalASTInsert.d.ts.map +1 -0
  26. package/dist/cjs/utils/SurgicalASTInsert.js +173 -0
  27. package/dist/cjs/utils/SurgicalASTInsert.js.map +1 -0
  28. package/dist/cjs/utils/SymbolSurgicalContext.d.ts +25 -0
  29. package/dist/cjs/utils/SymbolSurgicalContext.d.ts.map +1 -0
  30. package/dist/cjs/utils/SymbolSurgicalContext.js +265 -0
  31. package/dist/cjs/utils/SymbolSurgicalContext.js.map +1 -0
  32. package/dist/cjs/utils/WormholeCompressor.d.ts +22 -0
  33. package/dist/cjs/utils/WormholeCompressor.d.ts.map +1 -0
  34. package/dist/cjs/utils/WormholeCompressor.js +152 -0
  35. package/dist/cjs/utils/WormholeCompressor.js.map +1 -0
  36. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  37. package/dist/esm/cli/lemma-proxy.js +2 -4
  38. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  39. package/dist/esm/mcp/index.js +1 -1
  40. package/dist/esm/mcp/tools.d.ts.map +1 -1
  41. package/dist/esm/mcp/tools.js +292 -71
  42. package/dist/esm/mcp/tools.js.map +1 -1
  43. package/dist/esm/subconscious/TheBrainV2.d.ts +102 -0
  44. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -0
  45. package/dist/esm/subconscious/TheBrainV2.js +431 -0
  46. package/dist/esm/subconscious/TheBrainV2.js.map +1 -0
  47. package/dist/esm/utils/ContextCollapser.d.ts +21 -0
  48. package/dist/esm/utils/ContextCollapser.d.ts.map +1 -0
  49. package/dist/esm/utils/ContextCollapser.js +128 -0
  50. package/dist/esm/utils/ContextCollapser.js.map +1 -0
  51. package/dist/esm/utils/ExecutiveReport.d.ts +29 -0
  52. package/dist/esm/utils/ExecutiveReport.d.ts.map +1 -0
  53. package/dist/esm/utils/ExecutiveReport.js +105 -0
  54. package/dist/esm/utils/ExecutiveReport.js.map +1 -0
  55. package/dist/esm/utils/SurgicalASTInsert.d.ts +21 -0
  56. package/dist/esm/utils/SurgicalASTInsert.d.ts.map +1 -0
  57. package/dist/esm/utils/SurgicalASTInsert.js +134 -0
  58. package/dist/esm/utils/SurgicalASTInsert.js.map +1 -0
  59. package/dist/esm/utils/SymbolSurgicalContext.d.ts +25 -0
  60. package/dist/esm/utils/SymbolSurgicalContext.d.ts.map +1 -0
  61. package/dist/esm/utils/SymbolSurgicalContext.js +226 -0
  62. package/dist/esm/utils/SymbolSurgicalContext.js.map +1 -0
  63. package/dist/esm/utils/WormholeCompressor.d.ts +22 -0
  64. package/dist/esm/utils/WormholeCompressor.d.ts.map +1 -0
  65. package/dist/esm/utils/WormholeCompressor.js +148 -0
  66. package/dist/esm/utils/WormholeCompressor.js.map +1 -0
  67. package/lemma-proxy.cjs +31 -14
  68. package/mcp-server.js +220 -0
  69. package/package.json +5 -1
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * ContextCollapser — Zero-dependency extraction summarizer for technical logs & history.
4
+ *
5
+ * Replaces: Ollama for summarize_long_text and compress_context.
6
+ * Algorithm: Query-Focused TF-IDF Centroid sentence extraction + Jaccard dedup.
7
+ * Latency: <15ms for 100k characters.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.splitIntoSentences = splitIntoSentences;
11
+ exports.collapseContext = collapseContext;
12
+ const TheBrainV2_1 = require("../subconscious/TheBrainV2");
13
+ /**
14
+ * Split text into logical blocks (sentences or log chunks).
15
+ */
16
+ function splitIntoSentences(text) {
17
+ // Regex to split by sentence boundary (dot/exclamation/question followed by space or newline)
18
+ // Also preserves code lines/blocks reasonably
19
+ const lines = text.split(/\r?\n/);
20
+ const blocks = [];
21
+ for (const line of lines) {
22
+ const trimmed = line.trim();
23
+ if (!trimmed)
24
+ continue;
25
+ // If it's a long sentence with dots, split it
26
+ if (trimmed.length > 120 && trimmed.includes('. ')) {
27
+ const parts = trimmed.split(/(?<=[.!?])\s+/);
28
+ blocks.push(...parts.filter(p => p.trim().length > 0));
29
+ }
30
+ else {
31
+ blocks.push(trimmed);
32
+ }
33
+ }
34
+ return blocks;
35
+ }
36
+ /**
37
+ * Jaccard similarity between two sentences.
38
+ */
39
+ function Jaccard(setA, setB) {
40
+ if (setA.size === 0 && setB.size === 0)
41
+ return 0;
42
+ let inter = 0;
43
+ for (const item of setA) {
44
+ if (setB.has(item))
45
+ inter++;
46
+ }
47
+ return inter / (setA.size + setB.size - inter);
48
+ }
49
+ /**
50
+ * Summarize long text locally by selecting the most semantically dense sentences.
51
+ */
52
+ function collapseContext(text, options = {}) {
53
+ const maxLength = options.maxLength || 500;
54
+ const query = options.query || '';
55
+ if (!text || text.length <= maxLength) {
56
+ return text;
57
+ }
58
+ const sentences = splitIntoSentences(text);
59
+ if (sentences.length === 0)
60
+ return '';
61
+ // 1. Tokenize all sentences and build global vocabulary
62
+ const tokenizedSentences = sentences.map(s => new Set((0, TheBrainV2_1.tokenize)(s)));
63
+ const globalFreq = {};
64
+ for (const tokens of tokenizedSentences) {
65
+ for (const token of tokens) {
66
+ globalFreq[token] = (globalFreq[token] || 0) + 1;
67
+ }
68
+ }
69
+ // 2. Tokenize query if present
70
+ const queryTokens = new Set((0, TheBrainV2_1.tokenize)(query));
71
+ // 3. Score each sentence
72
+ const scoredSentences = sentences.map((sentence, index) => {
73
+ const tokens = tokenizedSentences[index];
74
+ if (tokens.size === 0)
75
+ return { sentence, score: 0, index, tokens };
76
+ let score = 0;
77
+ for (const token of tokens) {
78
+ // TF-IDF style weight: less common terms are worth more
79
+ const docFreq = globalFreq[token] || 1;
80
+ const idf = Math.log(sentences.length / docFreq + 1);
81
+ score += idf;
82
+ // Query boost
83
+ if (queryTokens.has(token)) {
84
+ score += idf * 2.5; // Boost keywords from query
85
+ }
86
+ }
87
+ // Length normalization to avoid favoring super long sentences
88
+ // Sweet spot length is 40-120 chars
89
+ const len = sentence.length;
90
+ let lengthFactor = 1.0;
91
+ if (len < 20)
92
+ lengthFactor = 0.4;
93
+ else if (len > 150)
94
+ lengthFactor = 150 / len; // Penalty for overly verbose logs
95
+ return {
96
+ sentence,
97
+ score: score * lengthFactor,
98
+ index,
99
+ tokens
100
+ };
101
+ });
102
+ // 4. Sort sentences by score descending
103
+ const sorted = [...scoredSentences].sort((a, b) => b.score - a.score);
104
+ // 5. Select sentences while staying under length budget & avoiding redundant info
105
+ const selected = [];
106
+ let currentLength = 0;
107
+ for (const candidate of sorted) {
108
+ if (candidate.score <= 0)
109
+ continue;
110
+ if (currentLength + candidate.sentence.length > maxLength && selected.length >= 2) {
111
+ continue;
112
+ }
113
+ // Check redundancy (Jaccard similarity with already selected sentences)
114
+ let isRedundant = false;
115
+ for (const sel of selected) {
116
+ if (Jaccard(candidate.tokens, sel.tokens) > 0.45) {
117
+ isRedundant = true;
118
+ break;
119
+ }
120
+ }
121
+ if (!isRedundant) {
122
+ selected.push(candidate);
123
+ currentLength += candidate.sentence.length + 1;
124
+ if (currentLength >= maxLength)
125
+ break;
126
+ }
127
+ }
128
+ // 6. Re-sort selected sentences by their original chronological index to maintain flow
129
+ selected.sort((a, b) => a.index - b.index);
130
+ return selected.map(s => s.sentence).join('\n');
131
+ }
132
+ //# sourceMappingURL=ContextCollapser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextCollapser.js","sourceRoot":"","sources":["../../../src/utils/ContextCollapser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * ExecutiveReport — Generator for corporate ROI & productivity metrics.
3
+ *
4
+ * Compiles session and lifetime statistics from the savings ledger, estimating
5
+ * financial savings, developer hours reclaimed, security compliance events, and
6
+ * scaling projections for presenting to executive corporate sponsors.
7
+ */
8
+ export interface ReportConfig {
9
+ teamSize?: number;
10
+ costPerDevHour?: number;
11
+ targetPath?: string;
12
+ }
13
+ export interface ReportMetrics {
14
+ totalTokensSaved: number;
15
+ totalCostSaved: number;
16
+ devHoursSaved: number;
17
+ devHoursUSD: number;
18
+ totalBusinessValue: number;
19
+ securityEventsCount: number;
20
+ }
21
+ /**
22
+ * Calculates metrics and writes a highly structured Markdown corporate report.
23
+ */
24
+ export declare function generateExecutiveReport(workspaceRoot: string, config?: ReportConfig): {
25
+ metrics: ReportMetrics;
26
+ markdown: string;
27
+ reportPath: string;
28
+ };
29
+ //# sourceMappingURL=ExecutiveReport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutiveReport.d.ts","sourceRoot":"","sources":["../../../src/utils/ExecutiveReport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,YAAiB,GACxB;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA2GlE"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * ExecutiveReport — Generator for corporate ROI & productivity metrics.
4
+ *
5
+ * Compiles session and lifetime statistics from the savings ledger, estimating
6
+ * financial savings, developer hours reclaimed, security compliance events, and
7
+ * scaling projections for presenting to executive corporate sponsors.
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.generateExecutiveReport = generateExecutiveReport;
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const path_1 = __importDefault(require("path"));
16
+ const SavingsLedger_1 = require("./SavingsLedger");
17
+ /**
18
+ * Calculates metrics and writes a highly structured Markdown corporate report.
19
+ */
20
+ function generateExecutiveReport(workspaceRoot, config = {}) {
21
+ const teamSize = config.teamSize || 10;
22
+ const costPerDevHour = config.costPerDevHour || 50;
23
+ const targetPath = config.targetPath || 'LEMMA_ROI_REPORT.md';
24
+ const reportPath = path_1.default.resolve(workspaceRoot, targetPath);
25
+ // 1. Gather ledger data
26
+ const snapshot = SavingsLedger_1.savingsLedger.getSnapshot();
27
+ // 2. Compute metrics
28
+ const totalTokensSaved = snapshot.total.tokensSaved;
29
+ const totalCostSaved = snapshot.total.costSaved;
30
+ // Estimate developer time saved:
31
+ // - 1 cache hit saves ~15 mins (0.25 hrs) of debug/reasoning.
32
+ // - 1 clipboard/context squeeze reduces prompt overhead & wait times, saving ~15 seconds (0.004 hrs) per event.
33
+ const cacheHits = snapshot.cache.events;
34
+ const squeezeEvents = snapshot.clipboard.events + snapshot.contextSqueeze.events + snapshot.historyPrune.events;
35
+ const devHoursSaved = Number((cacheHits * 0.25 + squeezeEvents * 0.004).toFixed(2));
36
+ const devHoursUSD = devHoursSaved * costPerDevHour;
37
+ const totalBusinessValue = totalCostSaved + devHoursUSD;
38
+ // Masked secrets count estimated from security events
39
+ const securityEventsCount = snapshot.clipboard.events; // Clipboard watcher scrubs automatically
40
+ // 3. Projections for scaling
41
+ const scaleTeams = [1, teamSize, teamSize * 5, teamSize * 10];
42
+ const projections = scaleTeams.map(size => {
43
+ // scale factor assuming other devs behave similarly
44
+ const scale = size;
45
+ return {
46
+ size,
47
+ monthlyTokens: Math.round(totalTokensSaved * scale * 22), // 22 working days
48
+ monthlyUSD: Number((totalCostSaved * scale * 22).toFixed(2)),
49
+ monthlyHours: Number((devHoursSaved * scale * 22).toFixed(1)),
50
+ monthlyROI: Number((totalBusinessValue * scale * 22).toFixed(2))
51
+ };
52
+ });
53
+ // 4. Build Markdown
54
+ const lines = [];
55
+ lines.push(`# 📊 Lemma Executive ROI & Cost Optimization Report`);
56
+ lines.push(`*Generated on: ${new Date().toLocaleDateString()} | Workspace: ${path_1.default.basename(workspaceRoot)}*`);
57
+ lines.push(``);
58
+ lines.push(`> [!IMPORTANT]`);
59
+ lines.push(`> **Executive Summary**: This report evaluates the direct business value, financial savings, and developer productivity hours reclaimed by implementing the **Lemma AI Gateway** in this workspace.`);
60
+ lines.push(``);
61
+ lines.push(`## 📈 Key Performance Indicators (KPIs)`);
62
+ lines.push(``);
63
+ lines.push(`| Metric | Value | Business Impact |`);
64
+ lines.push(`| :--- | :--- | :--- |`);
65
+ lines.push(`| **API Tokens Saved** | \`${totalTokensSaved.toLocaleString()}\` | Context optimization & deduplication |`);
66
+ lines.push(`| **Direct LLM Cost Saved** | \`$${totalCostSaved.toFixed(4)}\` | Real dollar savings on OpenAI / Anthropic billing |`);
67
+ lines.push(`| **Dev Time Reclaimed** | \`${devHoursSaved} Hours\` | Elimination of repetitive reasoning cycles |`);
68
+ lines.push(`| **Time Value Reclaimed** | \`$${devHoursUSD.toFixed(2)}\` | Productivity value based on $${costPerDevHour}/hr dev cost |`);
69
+ lines.push(`| **Total Business Value** | **$${totalBusinessValue.toFixed(2)}** | Combined Direct & Indirect Return on Investment |`);
70
+ lines.push(`| **Privacy Safeguards** | \`${securityEventsCount} Events\` | Auto-masked credentials/PII on clipboard |`);
71
+ lines.push(``);
72
+ lines.push(`## 🗜️ Savings Breakdown by Category`);
73
+ lines.push(``);
74
+ lines.push(`| Feature / Optimizer | Events | Est. Tokens Saved | Est. Cost Saved (USD) | Reclaimed Productivity |`);
75
+ lines.push(`| :--- | :---: | :---: | :---: | :---: |`);
76
+ lines.push(`| ⚡ **Semantic Cache (Brain)** | ${snapshot.cache.events} | ${snapshot.cache.tokensSaved.toLocaleString()} | $${snapshot.cache.costSaved.toFixed(4)} | ${(snapshot.cache.events * 0.25).toFixed(2)} hrs |`);
77
+ lines.push(`| 🗜️ **Context Squeezer & AST** | ${snapshot.contextSqueeze.events} | ${snapshot.contextSqueeze.tokensSaved.toLocaleString()} | $${snapshot.contextSqueeze.costSaved.toFixed(4)} | ${(snapshot.contextSqueeze.events * 0.004).toFixed(2)} hrs |`);
78
+ lines.push(`| 📜 **History Pruning (TextRank)** | ${snapshot.historyPrune.events} | ${snapshot.historyPrune.tokensSaved.toLocaleString()} | $${snapshot.historyPrune.costSaved.toFixed(4)} | ${(snapshot.historyPrune.events * 0.004).toFixed(2)} hrs |`);
79
+ lines.push(`| 📋 **Clipboard Compression** | ${snapshot.clipboard.events} | ${snapshot.clipboard.tokensSaved.toLocaleString()} | $${snapshot.clipboard.costSaved.toFixed(4)} | ${(snapshot.clipboard.events * 0.004).toFixed(2)} hrs |`);
80
+ lines.push(`| 🔀 **Complexity Routing** | ${snapshot.complexityRouting.events} | ${snapshot.complexityRouting.tokensSaved.toLocaleString()} | $${snapshot.complexityRouting.costSaved.toFixed(4)} | — |`);
81
+ lines.push(``);
82
+ lines.push(`## 🚀 Projections for Organization Scaling`);
83
+ lines.push(`Estimates for monthly and annual business value based on active usage across larger team scales:`);
84
+ lines.push(``);
85
+ lines.push(`| Team Size | Monthly Tokens Saved | Monthly API Savings (USD) | Monthly Dev Hours Saved | **Monthly Total Value (ROI)** |`);
86
+ lines.push(`| :---: | :---: | :---: | :---: | :--- |`);
87
+ for (const proj of projections) {
88
+ const boldPrefix = proj.size === teamSize ? '**' : '';
89
+ const boldSuffix = proj.size === teamSize ? '**' : '';
90
+ lines.push(`| ${boldPrefix}${proj.size} Devs${boldSuffix} | ${proj.monthlyTokens.toLocaleString()} | $${proj.monthlyUSD.toLocaleString()} | ${proj.monthlyHours} hrs | **$${proj.monthlyROI.toLocaleString()}** |`);
91
+ }
92
+ lines.push(``);
93
+ lines.push(`> [!TIP]`);
94
+ lines.push(`> **Security Compliance Note**: Lemma operates **entirely locally** using our zero-dependency AST parser and BM25 local indexing algorithms. No company code or intellectual property was transmitted to external servers for vector indexing, satisfying strict air-gapped corporate security compliance requirements.`);
95
+ const markdown = lines.join('\n');
96
+ // 5. Write to destination file
97
+ fs_1.default.writeFileSync(reportPath, markdown, 'utf8');
98
+ return {
99
+ metrics: {
100
+ totalTokensSaved,
101
+ totalCostSaved,
102
+ devHoursSaved,
103
+ devHoursUSD,
104
+ totalBusinessValue,
105
+ securityEventsCount
106
+ },
107
+ markdown,
108
+ reportPath
109
+ };
110
+ }
111
+ //# sourceMappingURL=ExecutiveReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutiveReport.js","sourceRoot":"","sources":["../../../src/utils/ExecutiveReport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * SurgicalASTInsert — AST-based surgical code insertion utility.
3
+ *
4
+ * Allows inserting methods, functions, or variable declarations inside a specific
5
+ * class, interface, or file scope, anchoring it relative to another symbol (e.g., "after method login").
6
+ *
7
+ * Prevents the LLM from outputting entire files or large search-replace blocks,
8
+ * reducing output token costs by up to 95%.
9
+ */
10
+ export interface ASTInsertOptions {
11
+ filePath: string;
12
+ symbolName?: string;
13
+ anchorSymbol?: string;
14
+ insertPosition?: 'before' | 'after' | 'start' | 'end';
15
+ codeToInsert: string;
16
+ }
17
+ /**
18
+ * Core orchestrator for Surgical AST insertion.
19
+ */
20
+ export declare function surgicalASTInsert(workspaceRoot: string, options: ASTInsertOptions): string;
21
+ //# sourceMappingURL=SurgicalASTInsert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SurgicalASTInsert.d.ts","sourceRoot":"","sources":["../../../src/utils/SurgicalASTInsert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACtD,YAAY,EAAE,MAAM,CAAC;CACtB;AAuBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAqG1F"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ /**
3
+ * SurgicalASTInsert — AST-based surgical code insertion utility.
4
+ *
5
+ * Allows inserting methods, functions, or variable declarations inside a specific
6
+ * class, interface, or file scope, anchoring it relative to another symbol (e.g., "after method login").
7
+ *
8
+ * Prevents the LLM from outputting entire files or large search-replace blocks,
9
+ * reducing output token costs by up to 95%.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.surgicalASTInsert = surgicalASTInsert;
49
+ const fs_1 = __importDefault(require("fs"));
50
+ const ts = __importStar(require("typescript"));
51
+ const utils_1 = require("../mcp/utils");
52
+ /**
53
+ * Finds a class or interface node by name.
54
+ */
55
+ function findTargetContainer(sourceFile, name) {
56
+ let result = null;
57
+ function walk(node) {
58
+ if (result)
59
+ return;
60
+ if (ts.isClassDeclaration(node) && node.name && node.name.text === name) {
61
+ result = node;
62
+ return;
63
+ }
64
+ if (ts.isInterfaceDeclaration(node) && node.name && node.name.text === name) {
65
+ result = node;
66
+ return;
67
+ }
68
+ ts.forEachChild(node, walk);
69
+ }
70
+ walk(sourceFile);
71
+ return result;
72
+ }
73
+ /**
74
+ * Core orchestrator for Surgical AST insertion.
75
+ */
76
+ function surgicalASTInsert(workspaceRoot, options) {
77
+ const { resolved } = (0, utils_1.safeResolvePath)(workspaceRoot, options.filePath);
78
+ if (!fs_1.default.existsSync(resolved)) {
79
+ throw new Error(`File not found: ${options.filePath}`);
80
+ }
81
+ const src = fs_1.default.readFileSync(resolved, 'utf8');
82
+ const sf = ts.createSourceFile(resolved, src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
83
+ const position = options.insertPosition || 'after';
84
+ let insertIndex = -1;
85
+ // Case A: Inserting inside a Class or Interface container
86
+ if (options.symbolName) {
87
+ const container = findTargetContainer(sf, options.symbolName);
88
+ if (!container) {
89
+ throw new Error(`Target container class/interface "${options.symbolName}" not found in file.`);
90
+ }
91
+ const members = container.members;
92
+ // Find anchor index among container members
93
+ let anchorIndex = -1;
94
+ if (options.anchorSymbol) {
95
+ anchorIndex = members.findIndex(m => {
96
+ if (ts.isMethodDeclaration(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
97
+ return true;
98
+ if (ts.isPropertyDeclaration(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
99
+ return true;
100
+ if (ts.isMethodSignature(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
101
+ return true;
102
+ if (ts.isPropertySignature(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
103
+ return true;
104
+ return false;
105
+ });
106
+ }
107
+ if (anchorIndex !== -1 && (position === 'after' || position === 'before')) {
108
+ const anchorNode = members[anchorIndex];
109
+ insertIndex = position === 'after' ? anchorNode.getEnd() : anchorNode.getStart();
110
+ }
111
+ else if (position === 'start' || members.length === 0) {
112
+ // Find open brace `{` index
113
+ const openBraceIndex = src.indexOf('{', container.getStart());
114
+ insertIndex = openBraceIndex + 1;
115
+ }
116
+ else {
117
+ // default to end of container (right before closing brace `}`)
118
+ const closeBraceIndex = container.getEnd() - 1;
119
+ insertIndex = closeBraceIndex;
120
+ }
121
+ }
122
+ // Case B: Inserting at file/module scope
123
+ else {
124
+ let anchorNode = null;
125
+ if (options.anchorSymbol) {
126
+ // Find top-level function or variable declaration matching anchorSymbol
127
+ for (const statement of sf.statements) {
128
+ if (ts.isFunctionDeclaration(statement) && statement.name && statement.name.text === options.anchorSymbol) {
129
+ anchorNode = statement;
130
+ break;
131
+ }
132
+ if (ts.isVariableStatement(statement)) {
133
+ for (const decl of statement.declarationList.declarations) {
134
+ if (ts.isIdentifier(decl.name) && decl.name.text === options.anchorSymbol) {
135
+ anchorNode = statement;
136
+ break;
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ if (anchorNode && (position === 'after' || position === 'before')) {
143
+ insertIndex = position === 'after' ? anchorNode.getEnd() : anchorNode.getStart();
144
+ }
145
+ else if (position === 'start') {
146
+ insertIndex = 0;
147
+ }
148
+ else {
149
+ // default: append to end of file
150
+ insertIndex = src.length;
151
+ }
152
+ }
153
+ if (insertIndex === -1) {
154
+ throw new Error('Could not resolve suitable insertion index.');
155
+ }
156
+ // Formatting insert block with appropriate indentation
157
+ // Look at the line of insertIndex to guess base indentation
158
+ const linesBefore = src.substring(0, insertIndex).split('\n');
159
+ const lastLine = linesBefore[linesBefore.length - 1] || '';
160
+ const indentMatch = lastLine.match(/^\s*/);
161
+ const baseIndent = indentMatch ? indentMatch[0] : ' ';
162
+ // Apply indentation to code to insert
163
+ const indentedCode = options.codeToInsert
164
+ .split('\n')
165
+ .map((line, idx) => (idx === 0 ? line : baseIndent + line))
166
+ .join('\n');
167
+ // Splice string
168
+ const output = src.substring(0, insertIndex) + '\n' + baseIndent + indentedCode + '\n' + src.substring(insertIndex);
169
+ // Write file
170
+ fs_1.default.writeFileSync(resolved, output, 'utf8');
171
+ return resolved;
172
+ }
173
+ //# sourceMappingURL=SurgicalASTInsert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SurgicalASTInsert.js","sourceRoot":"","sources":["../../../src/utils/SurgicalASTInsert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * SymbolSurgicalContext — Surgical AST extraction tool.
3
+ *
4
+ * Scans a file for a specific symbol (class, function, variable, interface),
5
+ * extracts its implementation, parses its AST to find workspace dependencies,
6
+ * and extracts ONLY the signatures of those dependencies (not their entire files).
7
+ *
8
+ * Saves up to 90% of token context in LLM prompts.
9
+ */
10
+ export interface SurgicalContextResult {
11
+ symbolName: string;
12
+ filePath: string;
13
+ implementation: string;
14
+ dependencies: Array<{
15
+ name: string;
16
+ filePath: string;
17
+ signature: string;
18
+ type: string;
19
+ }>;
20
+ }
21
+ /**
22
+ * Core orchestrator for Surgical Symbol Context Extraction.
23
+ */
24
+ export declare function getSymbolSurgicalContext(workspaceRoot: string, relativeFilePath: string, symbolName: string): SurgicalContextResult;
25
+ //# sourceMappingURL=SymbolSurgicalContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SymbolSurgicalContext.d.ts","sourceRoot":"","sources":["../../../src/utils/SymbolSurgicalContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAmLD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,GACjB,qBAAqB,CAmDvB"}