avocavo 1.1.4 → 1.2.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to the Avocavo CLI will be documented in this file.
4
4
 
5
+ ## [1.2.1] - 2026-03-31
6
+
7
+ ### ✨ Conversational Text Analysis
8
+ - **NEW**: Added `avocavo analyze <text>` command to seamlessly parse free-form, conversational meal text.
9
+ - **ENHANCED**: Implemented GPT-backed context inference to automatically resolve missing quantities (e.g., "butter" -> "1 pat butter") instead of reverting to 100g defaults.
10
+ - **IMPROVED**: Standardized JSON output structure to match the `/batch` endpoint schema for unified downstream processing.
11
+
5
12
  ## [1.1.1] - 2025-08-21
6
13
 
7
14
  ### ✨ UPC/Barcode Search Support
package/README.md CHANGED
@@ -27,7 +27,7 @@ avocavo --help
27
27
  - 🥗 **USDA Database** - Access to comprehensive nutrition data
28
28
  - 🧮 **Batch Analysis** - Analyze multiple ingredients at once
29
29
  - 📊 **Rich Output** - Beautiful tables and JSON formats
30
- - 🔒 **SSL Security** - All connections use verified HTTPS
30
+ - 🔒 **SSL Security** - All connections use secured HTTPS
31
31
 
32
32
  ## 📦 Installation
33
33
 
@@ -97,7 +97,7 @@ Remove stored credentials.
97
97
 
98
98
  ## 🔒 Security
99
99
 
100
- - **SSL Verification**: All API calls use verified HTTPS connections
100
+ - **SSL Verification**: All API calls use secured HTTPS connections
101
101
  - **Secure Storage**: Credentials stored in system keychain (not plaintext)
102
102
  - **OAuth Flow**: Secure browser-based authentication
103
103
  - **No Hardcoded Secrets**: All sensitive data handled securely
package/bin/avocavo.js CHANGED
@@ -663,6 +663,91 @@ program
663
663
  }
664
664
  });
665
665
 
666
+ // Free-text analyze command
667
+ program
668
+ .command('analyze <text>')
669
+ .description('Analyze free-form meal text — AI extracts and looks up each ingredient automatically')
670
+ .option('--verbose', 'Show detailed USDA info for each ingredient')
671
+ .action(async (text, options) => {
672
+ try {
673
+ const api = await getApiClient();
674
+ const globalOpts = program.opts();
675
+ const verbose = options.verbose || globalOpts.verbose;
676
+
677
+ console.log(chalk.cyan(`🤖 Analyzing: "${text}"...`));
678
+
679
+ const result = await api.analyzeText(text, verbose);
680
+
681
+ if (program.opts().json) {
682
+ console.log(JSON.stringify(result, null, 2));
683
+ return;
684
+ }
685
+
686
+ if (result.success) {
687
+ // Show what the AI extracted
688
+ const extracted = result.extracted_ingredients || [];
689
+ if (extracted.length > 0) {
690
+ console.log('');
691
+ console.log(chalk.bold('🔍 Detected ingredients:'));
692
+ extracted.forEach(ing => console.log(chalk.gray(` • ${ing}`)));
693
+ }
694
+
695
+ console.log('');
696
+ console.log(chalk.green(`✅ Analysis complete — ${result.summary.successful}/${result.batch_size || extracted.length} items matched`));
697
+ console.log('');
698
+
699
+ // Results table (same style as batch)
700
+ const tableData = (result.results || []).map(item => [
701
+ item.success ? '✅' : '❌',
702
+ item.ingredient,
703
+ item.success ? `${item.nutrition.calories}` : 'N/A',
704
+ item.success ? `${item.nutrition.protein}g` : 'N/A',
705
+ item.success ? `${item.nutrition.total_fat}g` : 'N/A',
706
+ item.success ? `${item.nutrition.carbohydrates}g` : 'N/A',
707
+ item.success ? `${item.nutrition.fiber}g` : 'N/A',
708
+ item.success ? `${item.nutrition.sodium}mg` : 'N/A'
709
+ ]);
710
+
711
+ if (tableData.length > 0) {
712
+ console.log(formatTable([
713
+ ['Status', 'Ingredient', 'Calories', 'Protein', 'Fat', 'Carbs', 'Fiber', 'Sodium'],
714
+ ...tableData
715
+ ]));
716
+ }
717
+
718
+ // Total calories summary
719
+ const totalCal = (result.results || [])
720
+ .filter(i => i.success)
721
+ .reduce((sum, i) => sum + (i.nutrition?.calories || 0), 0);
722
+ if (totalCal > 0) {
723
+ console.log('');
724
+ console.log(chalk.bold(`🔥 Total Calories: ${chalk.yellow(totalCal.toFixed(1))} kcal`));
725
+ }
726
+
727
+ // USDA sources (with --verbose)
728
+ if (verbose) {
729
+ const withUSDA = (result.results || []).filter(i => i.success && i.metadata?.usda_match);
730
+ if (withUSDA.length > 0) {
731
+ console.log('');
732
+ console.log(chalk.bold('🔗 USDA Sources:'));
733
+ withUSDA.forEach(item => {
734
+ const usda = item.metadata.usda_match;
735
+ console.log(chalk.gray(` ${item.ingredient} → ${usda.description} (FDC: ${usda.fdc_id})`));
736
+ });
737
+ }
738
+ }
739
+
740
+ } else {
741
+ console.log(chalk.red(`❌ ${result.error || 'Analysis failed'}`));
742
+ console.log(chalk.cyan('💡 Try rephrasing or use: avocavo batch --ingredients "item1" "item2"'));
743
+ process.exit(1);
744
+ }
745
+ } catch (error) {
746
+ console.error(chalk.red(`❌ Analyze error: ${error.message}`));
747
+ process.exit(1);
748
+ }
749
+ });
750
+
666
751
  // UPC/Barcode search command
667
752
  program
668
753
  .command('upc <upc>')
package/lib/api.js CHANGED
@@ -41,6 +41,17 @@ class NutritionAPI {
41
41
  }
42
42
  }
43
43
 
44
+ async analyzeText(text, verbose = false) {
45
+ try {
46
+ const response = await this.client.post(`${this.baseUrl}/api/v2/nutrition/analyze`, {
47
+ text: text
48
+ });
49
+ return response.data;
50
+ } catch (error) {
51
+ throw this.handleError(error);
52
+ }
53
+ }
54
+
44
55
  async analyzeRecipe(ingredients, servings = 1, verbose = false) {
45
56
  try {
46
57
  const response = await this.client.post(`${this.baseUrl}/api/v2/nutrition/recipe`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "avocavo",
3
- "version": "1.1.4",
3
+ "version": "1.2.1",
4
4
  "description": "Avocavo CLI - Structured nutrition data API with USDA-based calculations where applicable. Consistent nutrition estimates for apps and workflows. For informational use only. Not affiliated with or endorsed by USDA.",
5
5
  "main": "index.js",
6
6
  "bin": {