minovative-mind-cli 2.1.1 → 2.1.2
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 +3 -0
- package/dist/services/agent-tools.js +140 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ the build/performance metrics are green.
|
|
|
15
15
|
[](https://oclif.io)
|
|
16
16
|
[](https://npmjs.org/package/minovative-mind-cli)
|
|
17
17
|
[](https://npmjs.org/package/minovative-mind-cli)
|
|
18
|
+
[](https://nodejs.org)
|
|
19
|
+
[](https://www.typescriptlang.org/)
|
|
20
|
+
[](https://github.com/quarantiine/minovative-mind-cli/blob/main/LICENSE.md)
|
|
18
21
|
|
|
19
22
|
- Official Website: [Main Website](https://www.minovativemind.dev/)
|
|
20
23
|
- Latest Updates: [Updates](https://www.minovativemind.dev/updates)
|
|
@@ -361,7 +361,147 @@ export async function readFile(workspaceRoot, filePath, startLine, endLine, targ
|
|
|
361
361
|
inlineData: { mimeType: 'application/pdf', data: base64Data },
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
|
+
// Prevent reading massive lockfiles
|
|
365
|
+
const isLockfile = ['package-lock.json', 'yarn.lock', 'poetry.lock', 'pnpm-lock.yaml'].some(file => filePath.toLowerCase().endsWith(file));
|
|
366
|
+
if (isLockfile) {
|
|
367
|
+
return {
|
|
368
|
+
output: '',
|
|
369
|
+
error: `Do not read lockfiles directly as they waste thousands of tokens. Please read the 'package.json', 'pyproject.toml', or equivalent source file to see dependencies.`,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
// Handle SQLite databases natively by dumping the schema
|
|
373
|
+
if (filePath.toLowerCase().endsWith('.sqlite') || filePath.toLowerCase().endsWith('.db')) {
|
|
374
|
+
try {
|
|
375
|
+
const { stdout } = await execAsync(`sqlite3 "${absPath}" ".schema"`);
|
|
376
|
+
return {
|
|
377
|
+
output: `## Database Schema for ${path.basename(absPath)}\n\`\`\`sql\n${stdout}\n\`\`\``,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
catch (e) {
|
|
381
|
+
return {
|
|
382
|
+
output: '',
|
|
383
|
+
error: `Could not parse SQLite DB natively. Ensure 'sqlite3' CLI is installed. Error: ${e instanceof Error ? e.message : String(e)}`,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
364
387
|
let content = await fs.readFile(absPath, 'utf-8');
|
|
388
|
+
// Handle Jupyter Notebooks natively
|
|
389
|
+
if (filePath.toLowerCase().endsWith('.ipynb')) {
|
|
390
|
+
try {
|
|
391
|
+
const notebook = JSON.parse(content);
|
|
392
|
+
if (notebook && Array.isArray(notebook.cells)) {
|
|
393
|
+
const cleanCells = [];
|
|
394
|
+
for (const cell of notebook.cells) {
|
|
395
|
+
const sourceArray = Array.isArray(cell.source) ? cell.source : [cell.source || ''];
|
|
396
|
+
const source = sourceArray.join('');
|
|
397
|
+
if (cell.cell_type === 'markdown') {
|
|
398
|
+
cleanCells.push(source);
|
|
399
|
+
}
|
|
400
|
+
else if (cell.cell_type === 'code') {
|
|
401
|
+
let cellStr = '```python\n' + source + '\n```';
|
|
402
|
+
if (cell.outputs && Array.isArray(cell.outputs)) {
|
|
403
|
+
const textOutputs = [];
|
|
404
|
+
for (const out of cell.outputs) {
|
|
405
|
+
if (out.output_type === 'stream' && out.text) {
|
|
406
|
+
const text = Array.isArray(out.text) ? out.text.join('') : out.text;
|
|
407
|
+
textOutputs.push(text);
|
|
408
|
+
}
|
|
409
|
+
else if (out.data) {
|
|
410
|
+
if (out.data['text/plain']) {
|
|
411
|
+
const text = Array.isArray(out.data['text/plain']) ? out.data['text/plain'].join('') : out.data['text/plain'];
|
|
412
|
+
textOutputs.push(text);
|
|
413
|
+
}
|
|
414
|
+
else if (out.data['image/png'] || out.data['image/jpeg'] || out.data['image/svg+xml']) {
|
|
415
|
+
textOutputs.push('[Image Output]');
|
|
416
|
+
}
|
|
417
|
+
else if (out.data['text/html']) {
|
|
418
|
+
textOutputs.push('[HTML Output]');
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (textOutputs.length > 0) {
|
|
423
|
+
let joinedOutput = textOutputs.join('\n').trim();
|
|
424
|
+
const outLines = joinedOutput.split('\n');
|
|
425
|
+
if (outLines.length > 50) {
|
|
426
|
+
joinedOutput = outLines.slice(0, 50).join('\n') + '\n... (Output truncated)';
|
|
427
|
+
}
|
|
428
|
+
cellStr += '\n\n**Output:**\n```text\n' + joinedOutput + '\n```';
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
cleanCells.push(cellStr);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
content = cleanCells.join('\n\n');
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch (err) {
|
|
438
|
+
content = `<!-- Failed to parse .ipynb cleanly, showing raw JSON -->\n${content}`;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Handle CSV natively by formatting as a Markdown table
|
|
442
|
+
if (filePath.toLowerCase().endsWith('.csv')) {
|
|
443
|
+
try {
|
|
444
|
+
const rows = [];
|
|
445
|
+
let currentRow = [];
|
|
446
|
+
let currentCell = '';
|
|
447
|
+
let inQuotes = false;
|
|
448
|
+
for (let i = 0; i < content.length; i++) {
|
|
449
|
+
const char = content[i];
|
|
450
|
+
if (char === '"') {
|
|
451
|
+
if (inQuotes && content[i + 1] === '"') {
|
|
452
|
+
currentCell += '"';
|
|
453
|
+
i++;
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
inQuotes = !inQuotes;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else if (char === ',' && !inQuotes) {
|
|
460
|
+
currentRow.push(currentCell.trim().replace(/\n/g, ' ').replace(/\|/g, '\\|'));
|
|
461
|
+
currentCell = '';
|
|
462
|
+
}
|
|
463
|
+
else if ((char === '\n' || char === '\r') && !inQuotes) {
|
|
464
|
+
if (char === '\r' && content[i + 1] === '\n')
|
|
465
|
+
i++;
|
|
466
|
+
currentRow.push(currentCell.trim().replace(/\n/g, ' ').replace(/\|/g, '\\|'));
|
|
467
|
+
if (currentRow.some(cell => cell.length > 0)) {
|
|
468
|
+
rows.push(currentRow);
|
|
469
|
+
}
|
|
470
|
+
currentRow = [];
|
|
471
|
+
currentCell = '';
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
currentCell += char;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
if (currentCell !== '' || currentRow.length > 0) {
|
|
478
|
+
currentRow.push(currentCell.trim().replace(/\n/g, ' ').replace(/\|/g, '\\|'));
|
|
479
|
+
if (currentRow.some(cell => cell.length > 0))
|
|
480
|
+
rows.push(currentRow);
|
|
481
|
+
}
|
|
482
|
+
if (rows.length > 0) {
|
|
483
|
+
const header = rows[0];
|
|
484
|
+
const MAX_CSV_ROWS = 250; // Generous truncation limit
|
|
485
|
+
const isTruncated = rows.length > MAX_CSV_ROWS;
|
|
486
|
+
const displayRows = isTruncated ? rows.slice(0, MAX_CSV_ROWS) : rows;
|
|
487
|
+
let mdTable = `| ${header.join(' | ')} |\n`;
|
|
488
|
+
mdTable += `| ${header.map(() => '---').join(' | ')} |\n`;
|
|
489
|
+
for (let i = 1; i < displayRows.length; i++) {
|
|
490
|
+
const row = displayRows[i];
|
|
491
|
+
while (row.length < header.length)
|
|
492
|
+
row.push('');
|
|
493
|
+
mdTable += `| ${row.slice(0, header.length).join(' | ')} |\n`;
|
|
494
|
+
}
|
|
495
|
+
if (isTruncated) {
|
|
496
|
+
mdTable += `\n*(Note: CSV truncated from ${rows.length} rows to ${MAX_CSV_ROWS} rows for safe viewing)*\n`;
|
|
497
|
+
}
|
|
498
|
+
content = mdTable;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
catch (err) {
|
|
502
|
+
content = `<!-- Failed to parse .csv as table, showing raw text -->\n${content}`;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
365
505
|
if (targetElements && targetElements.length > 0) {
|
|
366
506
|
content = extractSymbols(content, filePath, targetElements);
|
|
367
507
|
}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED