bunosh 0.2.3 → 0.3.1
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 +570 -13
- package/bunosh.js +90 -4
- package/index.js +12 -7
- package/package.json +7 -3
- package/src/init.js +12 -4
- package/src/io.js +55 -1
- package/src/open-editor.js +95 -0
- package/src/program.js +58 -29
- package/src/task.js +8 -0
- package/src/tasks/ai.js +143 -0
- package/src/tasks/shell.js +119 -0
package/README.md
CHANGED
|
@@ -373,23 +373,123 @@ Commands:
|
|
|
373
373
|
All Bunosh functions are available via `global.bunosh`:
|
|
374
374
|
|
|
375
375
|
```javascript
|
|
376
|
-
const { exec, fetch, writeToFile, copyFile, say, ask, yell, task } = global.bunosh;
|
|
376
|
+
const { exec, shell, fetch, writeToFile, copyFile, say, ask, yell, task } = global.bunosh;
|
|
377
377
|
```
|
|
378
378
|
|
|
379
|
-
### Shell Execution
|
|
379
|
+
### Shell Execution
|
|
380
|
+
|
|
381
|
+
Bunosh provides two ways to execute shell commands:
|
|
382
|
+
|
|
383
|
+
#### `exec` - Universal Shell Execution
|
|
384
|
+
|
|
385
|
+
Best for complex commands, cross-platform compatibility, and when you need real-time streaming output.
|
|
386
|
+
|
|
380
387
|
```javascript
|
|
381
|
-
//
|
|
382
|
-
await exec`
|
|
383
|
-
await exec`npm install`;
|
|
388
|
+
// Complex shell commands with pipes and redirections
|
|
389
|
+
await exec`find . -name "*.js" | grep -v node_modules | wc -l`;
|
|
390
|
+
await exec`npm install --verbose`; // Shows progress in real-time
|
|
391
|
+
await exec`docker build . | tee build.log`;
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### `shell` - Native Bun Shell (with Node.js fallback)
|
|
395
|
+
|
|
396
|
+
Best for simple commands when running under Bun for maximum performance.
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
// Simple, fast commands
|
|
400
|
+
await shell`pwd`;
|
|
401
|
+
await shell`echo "Hello World"`;
|
|
402
|
+
await shell`ls -la`;
|
|
403
|
+
await shell`cat package.json`;
|
|
404
|
+
```
|
|
384
405
|
|
|
385
|
-
|
|
406
|
+
#### When to Use Which?
|
|
407
|
+
|
|
408
|
+
**Use `shell` when:**
|
|
409
|
+
- ✅ Running under Bun for optimal performance
|
|
410
|
+
- ✅ Executing simple commands (`pwd`, `ls`, `echo`, `cat`)
|
|
411
|
+
- ✅ Want fastest possible execution
|
|
412
|
+
- ✅ Working with basic file operations
|
|
413
|
+
|
|
414
|
+
**Use `exec` when:**
|
|
415
|
+
- ✅ Need cross-platform compatibility (Node.js + Bun)
|
|
416
|
+
- ✅ Using complex shell features (pipes, redirections, command chaining)
|
|
417
|
+
- ✅ Want real-time streaming output for long-running commands
|
|
418
|
+
- ✅ Running package managers (`npm install`, `docker build`)
|
|
419
|
+
|
|
420
|
+
Both support the same API and return the same `TaskResult` object:
|
|
421
|
+
|
|
422
|
+
```javascript
|
|
423
|
+
// Both tasks support environment variables
|
|
424
|
+
await shell`echo $NODE_ENV`.env({ NODE_ENV: 'production' });
|
|
386
425
|
await exec`echo $NODE_ENV`.env({ NODE_ENV: 'production' });
|
|
387
426
|
|
|
388
|
-
//
|
|
427
|
+
// Both support working directory changes
|
|
428
|
+
await shell`pwd`.cwd('/tmp');
|
|
389
429
|
await exec`ls -la`.cwd('/tmp');
|
|
390
430
|
|
|
391
|
-
//
|
|
392
|
-
await
|
|
431
|
+
// Choose based on complexity and performance needs
|
|
432
|
+
await shell`cat package.json`; // Simple, fast
|
|
433
|
+
await exec`npm install --verbose`; // Complex, streaming
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
#### TaskResult Object
|
|
437
|
+
|
|
438
|
+
Both `exec` and `shell` return a `TaskResult` object with the following properties and methods:
|
|
439
|
+
|
|
440
|
+
```javascript
|
|
441
|
+
const result = await exec`ls -la`;
|
|
442
|
+
// or
|
|
443
|
+
const result = await shell`ls -la`;
|
|
444
|
+
|
|
445
|
+
// Properties
|
|
446
|
+
result.status // 'success' or 'fail'
|
|
447
|
+
result.output // Combined stdout/stderr as string
|
|
448
|
+
|
|
449
|
+
// Getters (boolean)
|
|
450
|
+
result.hasFailed // true if command failed (non-zero exit code)
|
|
451
|
+
result.hasSucceeded // true if command succeeded (exit code 0)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
#### Error Handling Examples
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
// Check command success
|
|
458
|
+
const result = await exec`npm test`;
|
|
459
|
+
if (result.hasSucceeded) {
|
|
460
|
+
say('✅ Tests passed!');
|
|
461
|
+
} else {
|
|
462
|
+
yell('❌ Tests failed!');
|
|
463
|
+
console.log(result.output); // Show error details
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Get command output
|
|
467
|
+
const result = await exec`git rev-parse HEAD`;
|
|
468
|
+
if (result.hasSucceeded) {
|
|
469
|
+
const commitHash = result.output.trim();
|
|
470
|
+
say(`Current commit: ${commitHash}`);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Handle failures gracefully
|
|
474
|
+
const result = await exec`optional-command-that-might-fail`;
|
|
475
|
+
if (result.hasFailed) {
|
|
476
|
+
say('Command failed, but continuing...');
|
|
477
|
+
console.log('Error output:', result.output);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Old vs New style comparison
|
|
481
|
+
// ❌ Old: Commands throw on failure
|
|
482
|
+
try {
|
|
483
|
+
await someOtherTaskRunner('failing-command');
|
|
484
|
+
} catch (error) {
|
|
485
|
+
// Handle error
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// ✅ New: Explicit success/failure handling
|
|
489
|
+
const result = await exec`failing-command`;
|
|
490
|
+
if (result.hasFailed) {
|
|
491
|
+
// Handle failure explicitly
|
|
492
|
+
}
|
|
393
493
|
```
|
|
394
494
|
|
|
395
495
|
### HTTP Requests (`fetch`)
|
|
@@ -414,20 +514,477 @@ copyFile('template.js', 'output.js');
|
|
|
414
514
|
```
|
|
415
515
|
|
|
416
516
|
### User Interaction
|
|
517
|
+
|
|
518
|
+
#### `ask()` - Interactive User Input
|
|
519
|
+
|
|
520
|
+
The `ask()` function provides flexible ways to get user input with smart parameter detection and multiple modes:
|
|
521
|
+
|
|
417
522
|
```javascript
|
|
418
|
-
//
|
|
523
|
+
// === SIMPLE SYNTAX WITH SMART DETECTION ===
|
|
524
|
+
|
|
525
|
+
// Basic text input
|
|
419
526
|
const name = await ask('What is your name?');
|
|
420
527
|
|
|
528
|
+
// Text input with default value
|
|
529
|
+
const projectName = await ask('Project name:', 'my-awesome-app');
|
|
530
|
+
|
|
531
|
+
// Boolean confirmation (auto-detects confirm type)
|
|
532
|
+
const shouldContinue = await ask('Continue with deployment?', true);
|
|
533
|
+
const forceUpdate = await ask('Force update?', false);
|
|
534
|
+
|
|
535
|
+
// Number input with default
|
|
536
|
+
const port = await ask('Enter port number:', 3000);
|
|
537
|
+
|
|
538
|
+
// Single choice selection (auto-detects from array)
|
|
539
|
+
const framework = await ask('Choose your framework:', [
|
|
540
|
+
'React', 'Vue', 'Angular', 'Svelte'
|
|
541
|
+
]);
|
|
542
|
+
|
|
543
|
+
// Multiple choice selection (array + options)
|
|
544
|
+
const features = await ask('Select features to include:', [
|
|
545
|
+
'TypeScript', 'ESLint', 'Prettier', 'Tests', 'CI/CD'
|
|
546
|
+
], { multiple: true });
|
|
547
|
+
|
|
548
|
+
// === ADVANCED OPTIONS SYNTAX ===
|
|
549
|
+
|
|
550
|
+
// Multiline text input (opens system editor)
|
|
551
|
+
const description = await ask('Enter project description:', {
|
|
552
|
+
multiline: true // Same as editor: true
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// Editor input with default content
|
|
556
|
+
const config = await ask('Edit configuration:', {
|
|
557
|
+
editor: true,
|
|
558
|
+
default: 'Initial content here...'
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
// Password input (hidden)
|
|
562
|
+
const password = await ask('Enter password:', {
|
|
563
|
+
type: 'password'
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
// Mixed: default value + additional options
|
|
567
|
+
const email = await ask('Email address:', 'user@example.com', {
|
|
568
|
+
validate: (input) => input.includes('@') || 'Please enter valid email'
|
|
569
|
+
});
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
#### Ask Function Signatures
|
|
573
|
+
|
|
574
|
+
```javascript
|
|
575
|
+
// Smart detection syntax
|
|
576
|
+
ask(question, defaultValue, options?)
|
|
577
|
+
ask(question, choices[], options?)
|
|
578
|
+
ask(question, options)
|
|
579
|
+
|
|
580
|
+
// Examples:
|
|
581
|
+
ask('Name?', 'John') // String default
|
|
582
|
+
ask('Continue?', true) // Boolean -> confirm type
|
|
583
|
+
ask('Port?', 3000) // Number default
|
|
584
|
+
ask('Color?', ['red', 'blue']) // Array -> choices
|
|
585
|
+
ask('Colors?', ['red', 'blue'], { multiple: true }) // Array + options
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
#### Ask Options Reference
|
|
589
|
+
|
|
590
|
+
| Parameter/Option | Type | Description | Example |
|
|
591
|
+
|------------------|------|-------------|---------|
|
|
592
|
+
| **Smart Detection** | | |
|
|
593
|
+
| `defaultValue` | String/Number | Sets default value for text/number input | `'John'`, `3000` |
|
|
594
|
+
| `defaultValue` | Boolean | Auto-detects as confirmation prompt | `true`, `false` |
|
|
595
|
+
| `choices` | Array | Auto-detects as selection list | `['A', 'B', 'C']` |
|
|
596
|
+
| **Options Object** | | |
|
|
597
|
+
| `multiple` | Boolean | Enables multiple selections (requires `choices`) | `true` |
|
|
598
|
+
| `multiline` | Boolean | Opens system editor for multi-line input | `true` |
|
|
599
|
+
| `editor` | Boolean | Opens system editor for multi-line input (same as `multiline`) | `true` |
|
|
600
|
+
| `default` | Any | Default value or content (when using options object) | `'default value'` |
|
|
601
|
+
| `type` | String | Input type: `'input'`, `'confirm'`, `'password'`, `'number'` | `'password'` |
|
|
602
|
+
| `validate` | Function | Custom validation function | `(input) => input.length > 0` |
|
|
603
|
+
|
|
604
|
+
#### Advanced Ask Examples
|
|
605
|
+
|
|
606
|
+
```javascript
|
|
607
|
+
/**
|
|
608
|
+
* Interactive project setup with smart syntax
|
|
609
|
+
*/
|
|
610
|
+
export async function setupProject() {
|
|
611
|
+
// Simple syntax with smart detection
|
|
612
|
+
const projectName = await ask('Project name:', 'my-awesome-project');
|
|
613
|
+
|
|
614
|
+
const projectType = await ask('Project type:', [
|
|
615
|
+
'Web App', 'API', 'CLI Tool', 'Library'
|
|
616
|
+
]);
|
|
617
|
+
|
|
618
|
+
const dependencies = await ask('Select dependencies:', [
|
|
619
|
+
'express', 'lodash', 'axios', 'moment', 'uuid'
|
|
620
|
+
], { multiple: true });
|
|
621
|
+
|
|
622
|
+
const useTypescript = await ask('Use TypeScript?', false);
|
|
623
|
+
|
|
624
|
+
// Editor input for complex configuration
|
|
625
|
+
const packageJson = await ask('Customize package.json:', {
|
|
626
|
+
editor: true,
|
|
627
|
+
default: JSON.stringify({
|
|
628
|
+
name: projectName,
|
|
629
|
+
version: '1.0.0',
|
|
630
|
+
description: '',
|
|
631
|
+
dependencies: {}
|
|
632
|
+
}, null, 2)
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
say(`Creating ${projectType}: ${projectName}`);
|
|
636
|
+
say(`Dependencies: ${dependencies.join(', ')}`);
|
|
637
|
+
say(`TypeScript: ${useTypescript ? 'Yes' : 'No'}`);
|
|
638
|
+
|
|
639
|
+
writeToFile('package.json', packageJson);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Git commit with editor input
|
|
644
|
+
*/
|
|
645
|
+
export async function interactiveCommit() {
|
|
646
|
+
const message = await ask('Enter commit message:', {
|
|
647
|
+
editor: true,
|
|
648
|
+
default: 'feat: \n\n# Write your commit message above\n# First line: brief summary (50 chars max)\n# Blank line, then detailed explanation'
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
await exec`git commit -m "${message}"`;
|
|
652
|
+
say('✅ Committed successfully!');
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Database migration with smart syntax
|
|
657
|
+
*/
|
|
658
|
+
export async function migrate() {
|
|
659
|
+
// Smart array detection for choices
|
|
660
|
+
const action = await ask('Migration action:', [
|
|
661
|
+
'Run pending migrations',
|
|
662
|
+
'Rollback last migration',
|
|
663
|
+
'Reset database',
|
|
664
|
+
'Create new migration'
|
|
665
|
+
]);
|
|
666
|
+
|
|
667
|
+
if (action === 'Reset database') {
|
|
668
|
+
// Smart boolean detection for confirmation
|
|
669
|
+
const confirmed = await ask('⚠️ This will DELETE ALL DATA. Are you sure?', false);
|
|
670
|
+
|
|
671
|
+
if (!confirmed) {
|
|
672
|
+
say('Migration cancelled');
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// Execute migration based on selection...
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Server configuration with mixed smart syntax
|
|
682
|
+
*/
|
|
683
|
+
export async function configureServer() {
|
|
684
|
+
// Simple defaults
|
|
685
|
+
const serverName = await ask('Server name:', 'my-server');
|
|
686
|
+
const port = await ask('Port number:', 8080);
|
|
687
|
+
const enableHTTPS = await ask('Enable HTTPS?', true);
|
|
688
|
+
|
|
689
|
+
// Array with additional options
|
|
690
|
+
const databases = await ask('Select databases to connect:', [
|
|
691
|
+
'PostgreSQL', 'MongoDB', 'Redis', 'MySQL'
|
|
692
|
+
], { multiple: true });
|
|
693
|
+
|
|
694
|
+
// Mix of default + validation
|
|
695
|
+
const adminEmail = await ask('Admin email:', 'admin@example.com', {
|
|
696
|
+
validate: (email) => email.includes('@') || 'Please enter a valid email'
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
say(`Configuring ${serverName} on port ${port}`);
|
|
700
|
+
say(`HTTPS: ${enableHTTPS ? 'Enabled' : 'Disabled'}`);
|
|
701
|
+
say(`Databases: ${databases.join(', ')}`);
|
|
702
|
+
say(`Admin: ${adminEmail}`);
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
#### Output Functions
|
|
707
|
+
|
|
708
|
+
```javascript
|
|
421
709
|
// Output messages
|
|
422
|
-
say('Building project...'); // Normal output
|
|
423
|
-
yell('BUILD COMPLETE!'); // Emphasized output
|
|
710
|
+
say('Building project...'); // Normal output with !
|
|
711
|
+
yell('BUILD COMPLETE!'); // Emphasized ASCII art output
|
|
424
712
|
|
|
425
|
-
// Wrap long operations
|
|
713
|
+
// Wrap long operations with progress
|
|
426
714
|
await task('Installing dependencies', async () => {
|
|
427
715
|
await exec`npm install`;
|
|
428
716
|
});
|
|
429
717
|
```
|
|
430
718
|
|
|
719
|
+
## 🤖 AI-Powered Tasks
|
|
720
|
+
|
|
721
|
+
Bunosh now supports AI integration with structured outputs! Connect to popular AI providers and generate content, analyze data, or automate text processing with simple function calls.
|
|
722
|
+
|
|
723
|
+
### Quick Setup
|
|
724
|
+
|
|
725
|
+
Set your AI provider credentials:
|
|
726
|
+
```bash
|
|
727
|
+
# Required: Choose your model
|
|
728
|
+
export AI_MODEL=gpt-4o # or claude-3-5-sonnet-20241022, llama-3.3-70b-versatile, etc.
|
|
729
|
+
|
|
730
|
+
# Required: Set API key for your chosen provider
|
|
731
|
+
export OPENAI_API_KEY=your_key_here # for OpenAI models
|
|
732
|
+
# export ANTHROPIC_API_KEY=your_key_here # for Claude models
|
|
733
|
+
# export GROQ_API_KEY=your_key_here # for Groq models
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### Built-in AI Providers
|
|
737
|
+
|
|
738
|
+
- **OpenAI** - GPT-4o, GPT-4o-mini, GPT-3.5-turbo (via `OPENAI_API_KEY`)
|
|
739
|
+
- **Anthropic** - Claude 3.5 Sonnet, Claude 3 Haiku (via `ANTHROPIC_API_KEY`)
|
|
740
|
+
- **Groq** - Llama 3.3, Mixtral, Gemma models (via `GROQ_API_KEY` or `GROQ_KEY`)
|
|
741
|
+
|
|
742
|
+
### Custom AI Providers
|
|
743
|
+
|
|
744
|
+
For enterprise and custom setups, you can import and register any AI provider manually:
|
|
745
|
+
|
|
746
|
+
```javascript
|
|
747
|
+
const { ai } = global.bunosh;
|
|
748
|
+
|
|
749
|
+
// Method 1: Direct model configuration (most flexible)
|
|
750
|
+
import { bedrock } from '@ai-sdk/amazon-bedrock';
|
|
751
|
+
const bedrockModel = bedrock('anthropic.claude-3-sonnet-20240229-v1:0', {
|
|
752
|
+
region: 'us-east-1',
|
|
753
|
+
credentials: {
|
|
754
|
+
accessKeyId: 'your-access-key',
|
|
755
|
+
secretAccessKey: 'your-secret-key'
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
ai.configure({ model: bedrockModel });
|
|
760
|
+
|
|
761
|
+
// Method 2: Register custom provider with environment variable
|
|
762
|
+
import { xai } from '@ai-sdk/xai';
|
|
763
|
+
ai.configure({
|
|
764
|
+
registerProvider: {
|
|
765
|
+
envVar: 'XAI_API_KEY',
|
|
766
|
+
provider: {
|
|
767
|
+
createInstance: (modelName) => xai(modelName)
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
// Method 3: Register any custom provider (Azure OpenAI, OpenRouter, etc.)
|
|
773
|
+
import { openrouter } from '@openrouter/ai-sdk-provider';
|
|
774
|
+
ai.configure({
|
|
775
|
+
registerProvider: {
|
|
776
|
+
envVar: 'OPENROUTER_API_KEY',
|
|
777
|
+
provider: {
|
|
778
|
+
createInstance: (modelName) => openrouter(modelName)
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
// Method 4: Register completely custom provider
|
|
784
|
+
ai.configure({
|
|
785
|
+
registerProvider: {
|
|
786
|
+
envVar: 'CUSTOM_AI_API_KEY',
|
|
787
|
+
provider: {
|
|
788
|
+
createInstance: (modelName) => {
|
|
789
|
+
// Your custom provider logic
|
|
790
|
+
return customAIProvider(modelName, {
|
|
791
|
+
apiKey: process.env.CUSTOM_AI_API_KEY,
|
|
792
|
+
endpoint: 'https://custom-ai.company.com/v1'
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
// Reset to environment variable configuration
|
|
800
|
+
ai.reset();
|
|
801
|
+
|
|
802
|
+
// Check current configuration
|
|
803
|
+
const config = ai.getConfig();
|
|
804
|
+
console.log('Current AI config:', config);
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### AI Task Examples
|
|
808
|
+
|
|
809
|
+
```javascript
|
|
810
|
+
const { ai, writeToFile, say } = global.bunosh;
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Generate project documentation with AI
|
|
814
|
+
*/
|
|
815
|
+
export async function generateDocs() {
|
|
816
|
+
const codebase = fs.readFileSync('src/index.js', 'utf8');
|
|
817
|
+
|
|
818
|
+
const result = await ai(
|
|
819
|
+
`Generate documentation for this code: ${codebase}`,
|
|
820
|
+
{
|
|
821
|
+
overview: 'Brief project overview',
|
|
822
|
+
apiReference: 'API documentation',
|
|
823
|
+
examples: 'Usage examples',
|
|
824
|
+
installation: 'Installation instructions'
|
|
825
|
+
}
|
|
826
|
+
);
|
|
827
|
+
|
|
828
|
+
writeToFile('README.md', (line) => {
|
|
829
|
+
line`# ${result.overview}`;
|
|
830
|
+
line``;
|
|
831
|
+
line`## Installation`;
|
|
832
|
+
line`${result.installation}`;
|
|
833
|
+
line``;
|
|
834
|
+
line`## API Reference`;
|
|
835
|
+
line`${result.apiReference}`;
|
|
836
|
+
line``;
|
|
837
|
+
line`## Examples`;
|
|
838
|
+
line`${result.examples}`;
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
say('📚 Documentation generated!');
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Analyze and optimize code with AI suggestions
|
|
846
|
+
*/
|
|
847
|
+
export async function codeReview(filename) {
|
|
848
|
+
const code = fs.readFileSync(filename, 'utf8');
|
|
849
|
+
|
|
850
|
+
const analysis = await ai(
|
|
851
|
+
`Review this code for improvements: ${code}`,
|
|
852
|
+
{
|
|
853
|
+
issues: 'List of potential issues',
|
|
854
|
+
suggestions: 'Specific improvement suggestions',
|
|
855
|
+
security: 'Security considerations',
|
|
856
|
+
performance: 'Performance optimization tips',
|
|
857
|
+
rating: 'Overall code quality rating (1-10)'
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
|
|
861
|
+
say(`🔍 Code Review for ${filename}:`);
|
|
862
|
+
console.log(`Rating: ${analysis.rating}/10`);
|
|
863
|
+
console.log(`Issues: ${analysis.issues}`);
|
|
864
|
+
console.log(`Suggestions: ${analysis.suggestions}`);
|
|
865
|
+
console.log(`Security: ${analysis.security}`);
|
|
866
|
+
console.log(`Performance: ${analysis.performance}`);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Generate test cases from code
|
|
871
|
+
*/
|
|
872
|
+
export async function generateTests(sourceFile) {
|
|
873
|
+
const code = fs.readFileSync(sourceFile, 'utf8');
|
|
874
|
+
|
|
875
|
+
const tests = await ai(
|
|
876
|
+
`Generate comprehensive unit tests for this code: ${code}`,
|
|
877
|
+
{
|
|
878
|
+
testSuite: 'Complete test suite code',
|
|
879
|
+
edgeCases: 'List of edge cases covered',
|
|
880
|
+
mockSetup: 'Required mocks and setup code'
|
|
881
|
+
}
|
|
882
|
+
);
|
|
883
|
+
|
|
884
|
+
const testFile = sourceFile.replace('.js', '.test.js');
|
|
885
|
+
writeToFile(testFile, (line) => {
|
|
886
|
+
line`${tests.mockSetup}`;
|
|
887
|
+
line``;
|
|
888
|
+
line`${tests.testSuite}`;
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
say(`🧪 Tests generated: ${testFile}`);
|
|
892
|
+
say(`Edge cases: ${tests.edgeCases}`);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Create commit messages from git diff
|
|
897
|
+
*/
|
|
898
|
+
export async function smartCommit() {
|
|
899
|
+
const diff = await exec`git diff --staged`;
|
|
900
|
+
|
|
901
|
+
if (diff.hasFailed || !diff.output.trim()) {
|
|
902
|
+
say('No staged changes found');
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
const commit = await ai(
|
|
907
|
+
`Generate a commit message for these changes: ${diff.output}`,
|
|
908
|
+
{
|
|
909
|
+
title: 'Concise commit title (50 chars max)',
|
|
910
|
+
body: 'Detailed commit body explaining what and why',
|
|
911
|
+
type: 'Commit type (feat/fix/docs/refactor/test/chore)'
|
|
912
|
+
}
|
|
913
|
+
);
|
|
914
|
+
|
|
915
|
+
const message = `${commit.type}: ${commit.title}\n\n${commit.body}`;
|
|
916
|
+
await exec`git commit -m "${message}"`;
|
|
917
|
+
|
|
918
|
+
say(`✅ Committed with AI-generated message:`);
|
|
919
|
+
console.log(message);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Enterprise AI setup with custom provider
|
|
924
|
+
*/
|
|
925
|
+
export async function setupEnterpriseAI() {
|
|
926
|
+
// Import your enterprise AI provider
|
|
927
|
+
import { bedrock } from '@ai-sdk/amazon-bedrock';
|
|
928
|
+
|
|
929
|
+
// Configure for enterprise use
|
|
930
|
+
const enterpriseModel = bedrock('anthropic.claude-3-sonnet-20240229-v1:0', {
|
|
931
|
+
region: 'us-east-1'
|
|
932
|
+
// Uses AWS credentials from environment/profile
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
ai.configure({ model: enterpriseModel });
|
|
936
|
+
|
|
937
|
+
const analysis = await ai(
|
|
938
|
+
'Analyze our company performance from this quarterly report: [data]',
|
|
939
|
+
{
|
|
940
|
+
summary: 'Executive summary of performance',
|
|
941
|
+
risks: 'Identified business risks',
|
|
942
|
+
opportunities: 'Growth opportunities',
|
|
943
|
+
recommendations: 'Strategic recommendations'
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
|
|
947
|
+
say('📊 Enterprise AI analysis complete');
|
|
948
|
+
console.log(analysis);
|
|
949
|
+
}
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
### Simple Text Generation
|
|
953
|
+
|
|
954
|
+
For quick text generation without structured output:
|
|
955
|
+
|
|
956
|
+
```javascript
|
|
957
|
+
/**
|
|
958
|
+
* Generate marketing copy
|
|
959
|
+
*/
|
|
960
|
+
export async function generateCopy(product) {
|
|
961
|
+
const copy = await ai(`Write compelling marketing copy for: ${product}`);
|
|
962
|
+
say('📝 Generated copy:');
|
|
963
|
+
console.log(copy);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Translate content
|
|
968
|
+
*/
|
|
969
|
+
export async function translate(text, language = 'Spanish') {
|
|
970
|
+
const translation = await ai(`Translate to ${language}: ${text}`);
|
|
971
|
+
say(`🌐 Translation to ${language}:`);
|
|
972
|
+
console.log(translation);
|
|
973
|
+
}
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### Progressive Enhancement
|
|
977
|
+
|
|
978
|
+
The AI task features:
|
|
979
|
+
- **🎭 Animated Progress**: Braille spinner animation during generation
|
|
980
|
+
- **📊 Token Tracking**: Shows token usage for cost monitoring
|
|
981
|
+
- **⚡ Fast Inference**: Optimized for speed with Groq and other providers
|
|
982
|
+
- **🔧 Structured Output**: Get JSON responses with defined schemas
|
|
983
|
+
- **🎯 Provider Auto-Detection**: Automatically detects available API keys
|
|
984
|
+
- **💪 Error Handling**: Graceful handling of API errors and rate limits
|
|
985
|
+
|
|
986
|
+
Transform your development workflow with AI-powered automation! Generate documentation, analyze code, create tests, write commit messages, and much more.
|
|
987
|
+
|
|
431
988
|
## Command Features
|
|
432
989
|
|
|
433
990
|
### Automatic CLI Generation
|