@nxuss/lemma 0.9.2 → 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 +79 -12
  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 +911 -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 +911 -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,128 @@
1
+ /**
2
+ * ContextCollapser — Zero-dependency extraction summarizer for technical logs & history.
3
+ *
4
+ * Replaces: Ollama for summarize_long_text and compress_context.
5
+ * Algorithm: Query-Focused TF-IDF Centroid sentence extraction + Jaccard dedup.
6
+ * Latency: <15ms for 100k characters.
7
+ */
8
+ import { tokenize } from '../subconscious/TheBrainV2';
9
+ /**
10
+ * Split text into logical blocks (sentences or log chunks).
11
+ */
12
+ export function splitIntoSentences(text) {
13
+ // Regex to split by sentence boundary (dot/exclamation/question followed by space or newline)
14
+ // Also preserves code lines/blocks reasonably
15
+ const lines = text.split(/\r?\n/);
16
+ const blocks = [];
17
+ for (const line of lines) {
18
+ const trimmed = line.trim();
19
+ if (!trimmed)
20
+ continue;
21
+ // If it's a long sentence with dots, split it
22
+ if (trimmed.length > 120 && trimmed.includes('. ')) {
23
+ const parts = trimmed.split(/(?<=[.!?])\s+/);
24
+ blocks.push(...parts.filter(p => p.trim().length > 0));
25
+ }
26
+ else {
27
+ blocks.push(trimmed);
28
+ }
29
+ }
30
+ return blocks;
31
+ }
32
+ /**
33
+ * Jaccard similarity between two sentences.
34
+ */
35
+ function Jaccard(setA, setB) {
36
+ if (setA.size === 0 && setB.size === 0)
37
+ return 0;
38
+ let inter = 0;
39
+ for (const item of setA) {
40
+ if (setB.has(item))
41
+ inter++;
42
+ }
43
+ return inter / (setA.size + setB.size - inter);
44
+ }
45
+ /**
46
+ * Summarize long text locally by selecting the most semantically dense sentences.
47
+ */
48
+ export function collapseContext(text, options = {}) {
49
+ const maxLength = options.maxLength || 500;
50
+ const query = options.query || '';
51
+ if (!text || text.length <= maxLength) {
52
+ return text;
53
+ }
54
+ const sentences = splitIntoSentences(text);
55
+ if (sentences.length === 0)
56
+ return '';
57
+ // 1. Tokenize all sentences and build global vocabulary
58
+ const tokenizedSentences = sentences.map(s => new Set(tokenize(s)));
59
+ const globalFreq = {};
60
+ for (const tokens of tokenizedSentences) {
61
+ for (const token of tokens) {
62
+ globalFreq[token] = (globalFreq[token] || 0) + 1;
63
+ }
64
+ }
65
+ // 2. Tokenize query if present
66
+ const queryTokens = new Set(tokenize(query));
67
+ // 3. Score each sentence
68
+ const scoredSentences = sentences.map((sentence, index) => {
69
+ const tokens = tokenizedSentences[index];
70
+ if (tokens.size === 0)
71
+ return { sentence, score: 0, index, tokens };
72
+ let score = 0;
73
+ for (const token of tokens) {
74
+ // TF-IDF style weight: less common terms are worth more
75
+ const docFreq = globalFreq[token] || 1;
76
+ const idf = Math.log(sentences.length / docFreq + 1);
77
+ score += idf;
78
+ // Query boost
79
+ if (queryTokens.has(token)) {
80
+ score += idf * 2.5; // Boost keywords from query
81
+ }
82
+ }
83
+ // Length normalization to avoid favoring super long sentences
84
+ // Sweet spot length is 40-120 chars
85
+ const len = sentence.length;
86
+ let lengthFactor = 1.0;
87
+ if (len < 20)
88
+ lengthFactor = 0.4;
89
+ else if (len > 150)
90
+ lengthFactor = 150 / len; // Penalty for overly verbose logs
91
+ return {
92
+ sentence,
93
+ score: score * lengthFactor,
94
+ index,
95
+ tokens
96
+ };
97
+ });
98
+ // 4. Sort sentences by score descending
99
+ const sorted = [...scoredSentences].sort((a, b) => b.score - a.score);
100
+ // 5. Select sentences while staying under length budget & avoiding redundant info
101
+ const selected = [];
102
+ let currentLength = 0;
103
+ for (const candidate of sorted) {
104
+ if (candidate.score <= 0)
105
+ continue;
106
+ if (currentLength + candidate.sentence.length > maxLength && selected.length >= 2) {
107
+ continue;
108
+ }
109
+ // Check redundancy (Jaccard similarity with already selected sentences)
110
+ let isRedundant = false;
111
+ for (const sel of selected) {
112
+ if (Jaccard(candidate.tokens, sel.tokens) > 0.45) {
113
+ isRedundant = true;
114
+ break;
115
+ }
116
+ }
117
+ if (!isRedundant) {
118
+ selected.push(candidate);
119
+ currentLength += candidate.sentence.length + 1;
120
+ if (currentLength >= maxLength)
121
+ break;
122
+ }
123
+ }
124
+ // 6. Re-sort selected sentences by their original chronological index to maintain flow
125
+ selected.sort((a, b) => a.index - b.index);
126
+ return selected.map(s => s.sentence).join('\n');
127
+ }
128
+ //# 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,105 @@
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
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { savingsLedger } from './SavingsLedger';
11
+ /**
12
+ * Calculates metrics and writes a highly structured Markdown corporate report.
13
+ */
14
+ export function generateExecutiveReport(workspaceRoot, config = {}) {
15
+ const teamSize = config.teamSize || 10;
16
+ const costPerDevHour = config.costPerDevHour || 50;
17
+ const targetPath = config.targetPath || 'LEMMA_ROI_REPORT.md';
18
+ const reportPath = path.resolve(workspaceRoot, targetPath);
19
+ // 1. Gather ledger data
20
+ const snapshot = savingsLedger.getSnapshot();
21
+ // 2. Compute metrics
22
+ const totalTokensSaved = snapshot.total.tokensSaved;
23
+ const totalCostSaved = snapshot.total.costSaved;
24
+ // Estimate developer time saved:
25
+ // - 1 cache hit saves ~15 mins (0.25 hrs) of debug/reasoning.
26
+ // - 1 clipboard/context squeeze reduces prompt overhead & wait times, saving ~15 seconds (0.004 hrs) per event.
27
+ const cacheHits = snapshot.cache.events;
28
+ const squeezeEvents = snapshot.clipboard.events + snapshot.contextSqueeze.events + snapshot.historyPrune.events;
29
+ const devHoursSaved = Number((cacheHits * 0.25 + squeezeEvents * 0.004).toFixed(2));
30
+ const devHoursUSD = devHoursSaved * costPerDevHour;
31
+ const totalBusinessValue = totalCostSaved + devHoursUSD;
32
+ // Masked secrets count estimated from security events
33
+ const securityEventsCount = snapshot.clipboard.events; // Clipboard watcher scrubs automatically
34
+ // 3. Projections for scaling
35
+ const scaleTeams = [1, teamSize, teamSize * 5, teamSize * 10];
36
+ const projections = scaleTeams.map(size => {
37
+ // scale factor assuming other devs behave similarly
38
+ const scale = size;
39
+ return {
40
+ size,
41
+ monthlyTokens: Math.round(totalTokensSaved * scale * 22), // 22 working days
42
+ monthlyUSD: Number((totalCostSaved * scale * 22).toFixed(2)),
43
+ monthlyHours: Number((devHoursSaved * scale * 22).toFixed(1)),
44
+ monthlyROI: Number((totalBusinessValue * scale * 22).toFixed(2))
45
+ };
46
+ });
47
+ // 4. Build Markdown
48
+ const lines = [];
49
+ lines.push(`# 📊 Lemma Executive ROI & Cost Optimization Report`);
50
+ lines.push(`*Generated on: ${new Date().toLocaleDateString()} | Workspace: ${path.basename(workspaceRoot)}*`);
51
+ lines.push(``);
52
+ lines.push(`> [!IMPORTANT]`);
53
+ 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.`);
54
+ lines.push(``);
55
+ lines.push(`## 📈 Key Performance Indicators (KPIs)`);
56
+ lines.push(``);
57
+ lines.push(`| Metric | Value | Business Impact |`);
58
+ lines.push(`| :--- | :--- | :--- |`);
59
+ lines.push(`| **API Tokens Saved** | \`${totalTokensSaved.toLocaleString()}\` | Context optimization & deduplication |`);
60
+ lines.push(`| **Direct LLM Cost Saved** | \`$${totalCostSaved.toFixed(4)}\` | Real dollar savings on OpenAI / Anthropic billing |`);
61
+ lines.push(`| **Dev Time Reclaimed** | \`${devHoursSaved} Hours\` | Elimination of repetitive reasoning cycles |`);
62
+ lines.push(`| **Time Value Reclaimed** | \`$${devHoursUSD.toFixed(2)}\` | Productivity value based on $${costPerDevHour}/hr dev cost |`);
63
+ lines.push(`| **Total Business Value** | **$${totalBusinessValue.toFixed(2)}** | Combined Direct & Indirect Return on Investment |`);
64
+ lines.push(`| **Privacy Safeguards** | \`${securityEventsCount} Events\` | Auto-masked credentials/PII on clipboard |`);
65
+ lines.push(``);
66
+ lines.push(`## 🗜️ Savings Breakdown by Category`);
67
+ lines.push(``);
68
+ lines.push(`| Feature / Optimizer | Events | Est. Tokens Saved | Est. Cost Saved (USD) | Reclaimed Productivity |`);
69
+ lines.push(`| :--- | :---: | :---: | :---: | :---: |`);
70
+ 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 |`);
71
+ 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 |`);
72
+ 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 |`);
73
+ lines.push(`| 📋 **Clipboard Compression** | ${snapshot.clipboard.events} | ${snapshot.clipboard.tokensSaved.toLocaleString()} | $${snapshot.clipboard.costSaved.toFixed(4)} | ${(snapshot.clipboard.events * 0.004).toFixed(2)} hrs |`);
74
+ lines.push(`| 🔀 **Complexity Routing** | ${snapshot.complexityRouting.events} | ${snapshot.complexityRouting.tokensSaved.toLocaleString()} | $${snapshot.complexityRouting.costSaved.toFixed(4)} | — |`);
75
+ lines.push(``);
76
+ lines.push(`## 🚀 Projections for Organization Scaling`);
77
+ lines.push(`Estimates for monthly and annual business value based on active usage across larger team scales:`);
78
+ lines.push(``);
79
+ lines.push(`| Team Size | Monthly Tokens Saved | Monthly API Savings (USD) | Monthly Dev Hours Saved | **Monthly Total Value (ROI)** |`);
80
+ lines.push(`| :---: | :---: | :---: | :---: | :--- |`);
81
+ for (const proj of projections) {
82
+ const boldPrefix = proj.size === teamSize ? '**' : '';
83
+ const boldSuffix = proj.size === teamSize ? '**' : '';
84
+ lines.push(`| ${boldPrefix}${proj.size} Devs${boldSuffix} | ${proj.monthlyTokens.toLocaleString()} | $${proj.monthlyUSD.toLocaleString()} | ${proj.monthlyHours} hrs | **$${proj.monthlyROI.toLocaleString()}** |`);
85
+ }
86
+ lines.push(``);
87
+ lines.push(`> [!TIP]`);
88
+ 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.`);
89
+ const markdown = lines.join('\n');
90
+ // 5. Write to destination file
91
+ fs.writeFileSync(reportPath, markdown, 'utf8');
92
+ return {
93
+ metrics: {
94
+ totalTokensSaved,
95
+ totalCostSaved,
96
+ devHoursSaved,
97
+ devHoursUSD,
98
+ totalBusinessValue,
99
+ securityEventsCount
100
+ },
101
+ markdown,
102
+ reportPath
103
+ };
104
+ }
105
+ //# 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,134 @@
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
+ import fs from 'fs';
11
+ import * as ts from 'typescript';
12
+ import { safeResolvePath } from '../mcp/utils';
13
+ /**
14
+ * Finds a class or interface node by name.
15
+ */
16
+ function findTargetContainer(sourceFile, name) {
17
+ let result = null;
18
+ function walk(node) {
19
+ if (result)
20
+ return;
21
+ if (ts.isClassDeclaration(node) && node.name && node.name.text === name) {
22
+ result = node;
23
+ return;
24
+ }
25
+ if (ts.isInterfaceDeclaration(node) && node.name && node.name.text === name) {
26
+ result = node;
27
+ return;
28
+ }
29
+ ts.forEachChild(node, walk);
30
+ }
31
+ walk(sourceFile);
32
+ return result;
33
+ }
34
+ /**
35
+ * Core orchestrator for Surgical AST insertion.
36
+ */
37
+ export function surgicalASTInsert(workspaceRoot, options) {
38
+ const { resolved } = safeResolvePath(workspaceRoot, options.filePath);
39
+ if (!fs.existsSync(resolved)) {
40
+ throw new Error(`File not found: ${options.filePath}`);
41
+ }
42
+ const src = fs.readFileSync(resolved, 'utf8');
43
+ const sf = ts.createSourceFile(resolved, src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
44
+ const position = options.insertPosition || 'after';
45
+ let insertIndex = -1;
46
+ // Case A: Inserting inside a Class or Interface container
47
+ if (options.symbolName) {
48
+ const container = findTargetContainer(sf, options.symbolName);
49
+ if (!container) {
50
+ throw new Error(`Target container class/interface "${options.symbolName}" not found in file.`);
51
+ }
52
+ const members = container.members;
53
+ // Find anchor index among container members
54
+ let anchorIndex = -1;
55
+ if (options.anchorSymbol) {
56
+ anchorIndex = members.findIndex(m => {
57
+ if (ts.isMethodDeclaration(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
58
+ return true;
59
+ if (ts.isPropertyDeclaration(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
60
+ return true;
61
+ if (ts.isMethodSignature(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
62
+ return true;
63
+ if (ts.isPropertySignature(m) && m.name && ts.isIdentifier(m.name) && m.name.text === options.anchorSymbol)
64
+ return true;
65
+ return false;
66
+ });
67
+ }
68
+ if (anchorIndex !== -1 && (position === 'after' || position === 'before')) {
69
+ const anchorNode = members[anchorIndex];
70
+ insertIndex = position === 'after' ? anchorNode.getEnd() : anchorNode.getStart();
71
+ }
72
+ else if (position === 'start' || members.length === 0) {
73
+ // Find open brace `{` index
74
+ const openBraceIndex = src.indexOf('{', container.getStart());
75
+ insertIndex = openBraceIndex + 1;
76
+ }
77
+ else {
78
+ // default to end of container (right before closing brace `}`)
79
+ const closeBraceIndex = container.getEnd() - 1;
80
+ insertIndex = closeBraceIndex;
81
+ }
82
+ }
83
+ // Case B: Inserting at file/module scope
84
+ else {
85
+ let anchorNode = null;
86
+ if (options.anchorSymbol) {
87
+ // Find top-level function or variable declaration matching anchorSymbol
88
+ for (const statement of sf.statements) {
89
+ if (ts.isFunctionDeclaration(statement) && statement.name && statement.name.text === options.anchorSymbol) {
90
+ anchorNode = statement;
91
+ break;
92
+ }
93
+ if (ts.isVariableStatement(statement)) {
94
+ for (const decl of statement.declarationList.declarations) {
95
+ if (ts.isIdentifier(decl.name) && decl.name.text === options.anchorSymbol) {
96
+ anchorNode = statement;
97
+ break;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ if (anchorNode && (position === 'after' || position === 'before')) {
104
+ insertIndex = position === 'after' ? anchorNode.getEnd() : anchorNode.getStart();
105
+ }
106
+ else if (position === 'start') {
107
+ insertIndex = 0;
108
+ }
109
+ else {
110
+ // default: append to end of file
111
+ insertIndex = src.length;
112
+ }
113
+ }
114
+ if (insertIndex === -1) {
115
+ throw new Error('Could not resolve suitable insertion index.');
116
+ }
117
+ // Formatting insert block with appropriate indentation
118
+ // Look at the line of insertIndex to guess base indentation
119
+ const linesBefore = src.substring(0, insertIndex).split('\n');
120
+ const lastLine = linesBefore[linesBefore.length - 1] || '';
121
+ const indentMatch = lastLine.match(/^\s*/);
122
+ const baseIndent = indentMatch ? indentMatch[0] : ' ';
123
+ // Apply indentation to code to insert
124
+ const indentedCode = options.codeToInsert
125
+ .split('\n')
126
+ .map((line, idx) => (idx === 0 ? line : baseIndent + line))
127
+ .join('\n');
128
+ // Splice string
129
+ const output = src.substring(0, insertIndex) + '\n' + baseIndent + indentedCode + '\n' + src.substring(insertIndex);
130
+ // Write file
131
+ fs.writeFileSync(resolved, output, 'utf8');
132
+ return resolved;
133
+ }
134
+ //# 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"}