genesis-ai-cli 7.4.8 → 7.5.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.
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ /**
3
+ * Genesis MCP Result Transformers
4
+ *
5
+ * Composable data transformations for MCP tool results.
6
+ * Pipe-style API for chaining transformations.
7
+ *
8
+ * Features:
9
+ * - Common transformers (extract, filter, map, reduce)
10
+ * - Domain-specific transformers (papers, search, code)
11
+ * - Type-safe pipeline composition
12
+ * - Error handling in pipelines
13
+ * - Custom transformer creation
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.transform = transform;
17
+ exports.transformAsync = transformAsync;
18
+ exports.extract = extract;
19
+ exports.filter = filter;
20
+ exports.map = map;
21
+ exports.reduce = reduce;
22
+ exports.take = take;
23
+ exports.sort = sort;
24
+ exports.unique = unique;
25
+ exports.groupBy = groupBy;
26
+ exports.defaultTo = defaultTo;
27
+ exports.pluck = pluck;
28
+ exports.flatten = flatten;
29
+ exports.extractPapers = extractPapers;
30
+ exports.extractSearchResults = extractSearchResults;
31
+ exports.normalizeSearchResult = normalizeSearchResult;
32
+ exports.normalizePaper = normalizePaper;
33
+ exports.minCitations = minCitations;
34
+ exports.sortByCitations = sortByCitations;
35
+ exports.extractCode = extractCode;
36
+ exports.extractUrls = extractUrls;
37
+ exports.summarize = summarize;
38
+ exports.toMarkdownList = toMarkdownList;
39
+ exports.toNumberedList = toNumberedList;
40
+ exports.compose = compose;
41
+ exports.tryPaths = tryPaths;
42
+ exports.when = when;
43
+ exports.processArxivResults = processArxivResults;
44
+ exports.processSearchResults = processSearchResults;
45
+ exports.extractKeyInfo = extractKeyInfo;
46
+ // ============================================================================
47
+ // Pipeline Implementation
48
+ // ============================================================================
49
+ class SyncPipeline {
50
+ data;
51
+ constructor(data) {
52
+ this.data = data;
53
+ }
54
+ pipe(transformer) {
55
+ return new SyncPipeline(transformer(this.data));
56
+ }
57
+ pipeAsync(transformer) {
58
+ return new AsyncPipelineImpl(Promise.resolve(this.data).then(transformer));
59
+ }
60
+ value() {
61
+ return this.data;
62
+ }
63
+ valueOr(fallback) {
64
+ return this.data ?? fallback;
65
+ }
66
+ }
67
+ class AsyncPipelineImpl {
68
+ dataPromise;
69
+ constructor(dataPromise) {
70
+ this.dataPromise = dataPromise;
71
+ }
72
+ pipe(transformer) {
73
+ return new AsyncPipelineImpl(this.dataPromise.then(transformer));
74
+ }
75
+ pipeAsync(transformer) {
76
+ return new AsyncPipelineImpl(this.dataPromise.then(transformer));
77
+ }
78
+ async value() {
79
+ return this.dataPromise;
80
+ }
81
+ async valueOr(fallback) {
82
+ try {
83
+ const result = await this.dataPromise;
84
+ return result ?? fallback;
85
+ }
86
+ catch {
87
+ return fallback;
88
+ }
89
+ }
90
+ }
91
+ function transform(data) {
92
+ return new SyncPipeline(data);
93
+ }
94
+ function transformAsync(data) {
95
+ return new AsyncPipelineImpl(data);
96
+ }
97
+ // ============================================================================
98
+ // Common Transformers
99
+ // ============================================================================
100
+ /**
101
+ * Extract a nested property by path
102
+ */
103
+ function extract(path) {
104
+ return (input) => {
105
+ const parts = path.split('.');
106
+ let current = input;
107
+ for (const part of parts) {
108
+ if (current === undefined || current === null)
109
+ return undefined;
110
+ current = current[part];
111
+ }
112
+ return current;
113
+ };
114
+ }
115
+ /**
116
+ * Filter an array
117
+ */
118
+ function filter(predicate) {
119
+ return (input) => (Array.isArray(input) ? input.filter(predicate) : []);
120
+ }
121
+ /**
122
+ * Map over an array
123
+ */
124
+ function map(mapper) {
125
+ return (input) => (Array.isArray(input) ? input.map(mapper) : []);
126
+ }
127
+ /**
128
+ * Reduce an array
129
+ */
130
+ function reduce(reducer, initial) {
131
+ return (input) => (Array.isArray(input) ? input.reduce(reducer, initial) : initial);
132
+ }
133
+ /**
134
+ * Take first N items
135
+ */
136
+ function take(n) {
137
+ return (input) => (Array.isArray(input) ? input.slice(0, n) : []);
138
+ }
139
+ /**
140
+ * Sort an array
141
+ */
142
+ function sort(compareFn) {
143
+ return (input) => (Array.isArray(input) ? [...input].sort(compareFn) : []);
144
+ }
145
+ /**
146
+ * Get unique items by key
147
+ */
148
+ function unique(keyFn = (x) => x) {
149
+ return (input) => {
150
+ if (!Array.isArray(input))
151
+ return [];
152
+ const seen = new Set();
153
+ return input.filter((item) => {
154
+ const key = keyFn(item);
155
+ if (seen.has(key))
156
+ return false;
157
+ seen.add(key);
158
+ return true;
159
+ });
160
+ };
161
+ }
162
+ /**
163
+ * Group by key
164
+ */
165
+ function groupBy(keyFn) {
166
+ return (input) => {
167
+ if (!Array.isArray(input))
168
+ return {};
169
+ return input.reduce((acc, item) => {
170
+ const key = keyFn(item);
171
+ if (!acc[key])
172
+ acc[key] = [];
173
+ acc[key].push(item);
174
+ return acc;
175
+ }, {});
176
+ };
177
+ }
178
+ /**
179
+ * Default value if null/undefined
180
+ */
181
+ function defaultTo(fallback) {
182
+ return (input) => input ?? fallback;
183
+ }
184
+ /**
185
+ * Pluck a property from each item
186
+ */
187
+ function pluck(key) {
188
+ return (input) => (Array.isArray(input) ? input.map((item) => item[key]) : []);
189
+ }
190
+ /**
191
+ * Flatten nested arrays
192
+ */
193
+ function flatten() {
194
+ return (input) => (Array.isArray(input) ? input.flat() : []);
195
+ }
196
+ // ============================================================================
197
+ // Domain-Specific Transformers (MCP Results)
198
+ // ============================================================================
199
+ /**
200
+ * Extract papers from arXiv/semantic-scholar results
201
+ */
202
+ function extractPapers() {
203
+ return (input) => {
204
+ if (!input)
205
+ return [];
206
+ return input.papers || input.results || input.data || [];
207
+ };
208
+ }
209
+ /**
210
+ * Extract search results from brave/exa/firecrawl
211
+ */
212
+ function extractSearchResults() {
213
+ return (input) => {
214
+ if (!input)
215
+ return [];
216
+ return (input.results ||
217
+ input.web?.results ||
218
+ input.data ||
219
+ input.pages ||
220
+ []);
221
+ };
222
+ }
223
+ function normalizeSearchResult() {
224
+ return (input) => ({
225
+ title: input.title || input.name || 'Untitled',
226
+ url: input.url || input.link || input.href || '',
227
+ description: input.description || input.snippet || input.abstract || '',
228
+ source: input.source || input.domain || extractDomain(input.url || ''),
229
+ });
230
+ }
231
+ function extractDomain(url) {
232
+ try {
233
+ return new URL(url).hostname;
234
+ }
235
+ catch {
236
+ return 'unknown';
237
+ }
238
+ }
239
+ function normalizePaper() {
240
+ return (input) => ({
241
+ id: input.id || input.paperId || input.arxivId || '',
242
+ title: input.title || 'Untitled',
243
+ authors: Array.isArray(input.authors)
244
+ ? input.authors.map((a) => (typeof a === 'string' ? a : a.name || ''))
245
+ : [],
246
+ abstract: input.abstract || input.summary || '',
247
+ url: input.url || input.link || `https://arxiv.org/abs/${input.id || ''}`,
248
+ year: input.year || input.publicationDate?.split('-')[0],
249
+ citations: input.citationCount || input.citations,
250
+ });
251
+ }
252
+ /**
253
+ * Filter by minimum citation count
254
+ */
255
+ function minCitations(min) {
256
+ return filter((paper) => (paper.citations || 0) >= min);
257
+ }
258
+ /**
259
+ * Sort papers by citations (descending)
260
+ */
261
+ function sortByCitations() {
262
+ return sort((a, b) => (b.citations || 0) - (a.citations || 0));
263
+ }
264
+ /**
265
+ * Extract code from firecrawl/exa results
266
+ */
267
+ function extractCode() {
268
+ return (input) => {
269
+ const content = input.content || input.markdown || input.text || '';
270
+ const codeBlockRegex = /```[\s\S]*?```/g;
271
+ const matches = content.match(codeBlockRegex) || [];
272
+ return matches.map((block) => block.replace(/```\w*\n?/g, '').trim());
273
+ };
274
+ }
275
+ /**
276
+ * Extract URLs from content
277
+ */
278
+ function extractUrls() {
279
+ return (input) => {
280
+ const content = typeof input === 'string' ? input : JSON.stringify(input);
281
+ const urlRegex = /https?:\/\/[^\s"'<>)]+/g;
282
+ return content.match(urlRegex) || [];
283
+ };
284
+ }
285
+ /**
286
+ * Summarize content to max length
287
+ */
288
+ function summarize(maxLength) {
289
+ return (input) => {
290
+ if (!input || input.length <= maxLength)
291
+ return input || '';
292
+ return input.slice(0, maxLength - 3) + '...';
293
+ };
294
+ }
295
+ /**
296
+ * Format as markdown list
297
+ */
298
+ function toMarkdownList() {
299
+ return (input) => Array.isArray(input) ? input.map((item) => `- ${item}`).join('\n') : '';
300
+ }
301
+ /**
302
+ * Format as numbered list
303
+ */
304
+ function toNumberedList() {
305
+ return (input) => Array.isArray(input) ? input.map((item, i) => `${i + 1}. ${item}`).join('\n') : '';
306
+ }
307
+ // ============================================================================
308
+ // Transformer Composition
309
+ // ============================================================================
310
+ /**
311
+ * Compose multiple transformers into one
312
+ */
313
+ function compose(...transformers) {
314
+ return (input) => {
315
+ return transformers.reduce((acc, transformer) => transformer(acc), input);
316
+ };
317
+ }
318
+ /**
319
+ * Create a transformer that tries multiple paths and returns first success
320
+ */
321
+ function tryPaths(...paths) {
322
+ return (input) => {
323
+ for (const path of paths) {
324
+ const result = extract(path)(input);
325
+ if (result !== undefined)
326
+ return result;
327
+ }
328
+ return undefined;
329
+ };
330
+ }
331
+ /**
332
+ * Conditional transformer
333
+ */
334
+ function when(predicate, thenTransform, elseTransform) {
335
+ return (input) => {
336
+ if (predicate(input)) {
337
+ return thenTransform(input);
338
+ }
339
+ return elseTransform ? elseTransform(input) : input;
340
+ };
341
+ }
342
+ // ============================================================================
343
+ // Prebuilt Pipelines
344
+ // ============================================================================
345
+ /**
346
+ * Process arXiv search results into normalized papers
347
+ */
348
+ function processArxivResults() {
349
+ return compose(extractPapers(), map(normalizePaper()), sortByCitations());
350
+ }
351
+ /**
352
+ * Process web search results into normalized format
353
+ */
354
+ function processSearchResults() {
355
+ return compose(extractSearchResults(), map(normalizeSearchResult()), unique((r) => r.url));
356
+ }
357
+ /**
358
+ * Extract and summarize key information
359
+ */
360
+ function extractKeyInfo(maxItems = 5) {
361
+ return compose(extractSearchResults(), map(normalizeSearchResult()), take(maxItems), map((r) => `${r.title}: ${summarize(100)(r.description)}`));
362
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genesis-ai-cli",
3
- "version": "7.4.8",
3
+ "version": "7.5.0",
4
4
  "description": "Autonomous AI System Creator - Brain ON by default, Active Inference integrated, Curiosity-driven, Φ monitoring in every response",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",