avocavo 1.1.3 → 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
@@ -1,6 +1,6 @@
1
1
  # 🥑 Avocavo CLI
2
2
 
3
- > Nutrition analysis made simple. Get accurate USDA nutrition data with secure authentication.
3
+ > Structured nutrition data API with USDA-based calculations where applicable. Consistent nutrition estimates for apps and workflows.
4
4
 
5
5
  ## 🚀 Quick Start
6
6
 
@@ -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
 
@@ -58,7 +58,7 @@ Analyze a single ingredient:
58
58
  ```bash
59
59
  avocavo ingredient "1 cup brown rice"
60
60
  avocavo ingredient "200g chicken breast"
61
- avocavo ingredient "1 cup rice" -v # Include USDA verification URL
61
+ avocavo ingredient "1 cup rice" -v # Include USDA FDC source URL
62
62
  ```
63
63
 
64
64
  ### `avocavo recipe [options]`
@@ -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
@@ -57,7 +57,7 @@ function secureReadFile(filePath) {
57
57
 
58
58
  program
59
59
  .name('avocavo')
60
- .description('Avocavo Nutrition API CLI - Fast, accurate nutrition data with USDA verification')
60
+ .description('Avocavo Nutrition API CLI - Structured nutrition data with USDA-based calculations and ingredient normalization')
61
61
  .version(version);
62
62
 
63
63
  // Global options
@@ -346,7 +346,7 @@ keysCmd
346
346
  program
347
347
  .command('ingredient <ingredient>')
348
348
  .description('Analyze a single ingredient for nutrition data')
349
- .option('-v, --verify', 'Include USDA verification URL')
349
+ .option('-v, --verify', 'Include USDA FDC source URL')
350
350
  .option('--verbose', 'Show detailed performance metrics and USDA info')
351
351
  .option('--debug', 'Show all available data (same as --json)')
352
352
  .option('--timing', 'Show processing time')
@@ -441,7 +441,7 @@ program
441
441
  .option('-s, --servings <number>', 'Number of servings', '1')
442
442
  .option('-i, --ingredients <ingredients...>', 'Recipe ingredients')
443
443
  .option('-f, --file <file>', 'Read ingredients from file (one per line)')
444
- .option('-v, --verify', 'Include USDA verification URLs for ingredients')
444
+ .option('-v, --verify', 'Include USDA FDC source URLs for ingredients')
445
445
  .option('--verbose', 'Show detailed performance metrics and USDA info')
446
446
  .option('--debug', 'Show all available data (same as --json)')
447
447
  .action(async (options) => {
@@ -529,7 +529,7 @@ program
529
529
 
530
530
  // Clean default: just show count
531
531
  const usdaCount = ingredientsWithUSDA.length;
532
- console.log(chalk.gray(`🎯 USDA verified: ${usdaCount}/${ingredients.length} ingredients`));
532
+ console.log(chalk.gray(`🎯 USDA matched: ${usdaCount}/${ingredients.length} ingredients`));
533
533
 
534
534
  // Detailed USDA info with --verbose or --verify
535
535
  if (options.verbose || options.verify) {
@@ -641,7 +641,7 @@ program
641
641
  // Show USDA verification details for successful ingredients
642
642
  if (result.results.some(item => item.success && item.metadata?.usda_match)) {
643
643
  console.log('');
644
- console.log(chalk.bold('🔗 USDA Verification:'));
644
+ console.log(chalk.bold('🔗 USDA Sources:'));
645
645
  result.results.forEach(item => {
646
646
  if (item.success && item.metadata?.usda_match) {
647
647
  const usda = item.metadata.usda_match;
@@ -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>')
@@ -1014,7 +1099,7 @@ Examples:
1014
1099
  $ avocavo keys switch # Switch active API key (interactive)
1015
1100
  $ avocavo keys delete # Delete API key (interactive)
1016
1101
  $ avocavo ingredient "1 cup rice" # Analyze single ingredient
1017
- $ avocavo ingredient "1 cup rice" -v # Include USDA verification URL
1102
+ $ avocavo ingredient "1 cup rice" -v # Include USDA FDC source URL
1018
1103
  $ avocavo recipe -i "2 cups flour" "1 cup milk" -s 8 # Analyze recipe
1019
1104
  $ avocavo batch -i "1 cup rice" "2 tbsp oil" "4 oz chicken" # Batch analysis
1020
1105
  $ avocavo upc "041196912395" # Search UPC/barcode
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/lib/formatters.js CHANGED
@@ -148,7 +148,7 @@ function formatUSDAMatch(usda, verificationUrl) {
148
148
  lines.push(` 🔗 Verify: ${chalk.underline(verificationUrl)}`);
149
149
  }
150
150
 
151
- return '\n' + chalk.gray('USDA Verification:') + '\n' + lines.join('\n');
151
+ return '\n' + chalk.gray('USDA Source:') + '\n' + lines.join('\n');
152
152
  }
153
153
 
154
154
  function formatTable(data, options = {}) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "avocavo",
3
- "version": "1.1.3",
4
- "description": "Avocavo CLI - Nutrition analysis made simple. Get accurate USDA nutrition data with secure authentication.",
3
+ "version": "1.2.1",
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": {
7
7
  "avocavo": "bin/avocavo.js"