Skill: runawaydevil/fipe-carros (version 1.0.0)

# Tabela FIPE Skill Consulta preços de veículos (carros, motos, caminhões) na Tabela FIPE brasileira. ## O que é a Tabela FIPE? A **Tabela FIPE** é uma referência oficial de preços médios de veículos no Brasil, calculada pela **Fundação Instituto de Pesquisas Econômicas (FIPE)** ligada à USP. Atualizada mensalmente, é usada para: - Compra e venda de veículos - Financiamentos e consórcios - Cálculo de seguros - Base para IPVA ## Gatilhos Ative a skill usando: - `"fipe"`, `"tabela fipe"` — buscar preço - `"preço carro"`, `"valor carro"` — consultar - `"carro tá quanto"` — consulta informal ## Como Usar ```bash # Listar marcas de carros node src/index.js marcas # Listar modelos de uma marca node src/index.js modelos 59 # 59 = Volkswagen # List anos de um modelo node src/index.js anos 59 5940 # Ver preço de um veículo node src/index.js preco 59 5940 2014-3 # Busca rápida por nome (pesquisa em todas as marcas) node src/index.js search "Hilux" ``` ## Busca Inteligente A skill suporta busca por nome que retorna modelos compatíveis: ```bash node src/index.js search "Toyota Corolla" node src/index.js search "Honda Civic" ``` ## API - **URL Base:** https://parallelum.com.br/fipe/api/v1 - **Autenticação:** Não requer API key - **Veículos:** carros, motos, caminhoes ## Exemplos de Códigos de Marcas | Código | Marca | |--------|-------| | 59 | Volkswagen | | 21 | Chevrolet | | 23 | Ford | | 33 | Fiat | | 2 | Honda (motos) | | 1 | Yamaha (motos) |

path: package-lock.json
content: {
  "name": "fipe-carros",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "fipe-carros",
      "version": "1.0.0",
      "dependencies": {
        "axios": "^1.6.0"
      }
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT"
    },
    "node_modules/axios": {
      "version": "1.13.6",
      "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "follow-redirects": "^1.15.11",
        "form-data": "^4.0.5",
        "proxy-from-env": "^1.1.0"
      }
    },
    "node_modules/call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-object-atoms": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/follow-redirects": {
      "version": "1.15.11",
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
      "integrity": [REDACTED_SECRET],
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/RubenVerborgh"
        }
      ],
      "license": "MIT",
      "engines": {
        "node": ">=4.0"
      },
      "peerDependenciesMeta": {
        "debug": {
          "optional": true
        }
      }
    },
    "node_modules/form-data": {
      "version": "4.0.5",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "hasown": "^2.0.2",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "has-symbols": "^1.0.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT"
    }
  }
}


path: package.json
content: {
  "name": "fipe-carros",
  "version": "1.0.0",
  "description": "Consulta preços de veículos na Tabela FIPE brasileira",
  "main": "src/index.js",
  "scripts": {
    "start": "node src/index.js"
  },
  "dependencies": {
    "axios": "^1.6.0"
  }
}


path: src/index.js
content: #!/usr/bin/env node

/**
 * Tabela FIPE Skill
 * Consulta preços de veículos na Tabela FIPE brasileira
 */

const axios = require('axios');

const BASE_URL = 'https://parallelum.com.br/fipe/api/v1';

// Fetch from FIPE API
async function fetchFIPE(endpoint) {
  const response = await axios.get(`${BASE_URL}${endpoint}`);
  return response.data;
}

// Get brands
async function getBrands(tipo = 'carros') {
  return fetchFIPE(`/${tipo}/marcas`);
}

// Get models
async function getModels(tipo, marcaId) {
  return fetchFIPE(`/${tipo}/marcas/${marcaId}/modelos`);
}

// Get years
async function getYears(tipo, marcaId, modeloId) {
  return fetchFIPE(`/${tipo}/marcas/${marcaId}/modelos/${modeloId}/anos`);
}

// Get price
async function getPrice(tipo, marcaId, modeloId, anoId) {
  return fetchFIPE(`/${tipo}/marcas/${marcaId}/modelos/${modeloId}/anos/${anoId}`);
}

// Search for a vehicle by name
async function searchVehicle(nome) {
  const tipo = 'carros';
  const brands = await getBrands(tipo);
  
  const nomeLower = nome.toLowerCase();
  const results = [];
  
  // Search in each brand (limited for performance)
  const brandsToSearch = brands.slice(0, 30); // Limit brands to search
  
  for (const brand of brandsToSearch) {
    try {
      const models = await getModels(tipo, brand.codigo);
      for (const model of models.modelos) {
        if (model.nome.toLowerCase().includes(nomeLower)) {
          results.push({
            brand: brand.nome,
            brandId: brand.codigo,
            model: model.nome,
            modelId: model.codigo
          });
        }
      }
    } catch (e) {
      // Skip errors
    }
  }
  
  return results;
}

// Format price response
function formatPrice(data) {
  if (!data) return 'Dados não encontrados.';
  
  return `🚗 ${data.Modelo}
📅 Ano: ${data.AnoModelo}
⛽ Combustível: ${data.Combustivel}
🔢 Código FIPE: ${data.CodigoFipe}

💰 Preço Tabela FIPE:
   ${data.Valor}
   
📊 Mês de referência: ${data.MesReferencia}

⚠️ Observação: ${data.ModeloCodigoExterno || 'Preço médio à vista'}`;
}

// Format brands
function formatBrands(brands) {
  let output = '🏷️ MARCAS DISPONÍVEIS (carros):\n\n';
  brands.slice(0, 30).forEach((b, i) => {
    output += `${String(b.codigo).padStart(3, '0')} - ${b.nome}\n`;
  });
  output += `\n... e mais ${brands.length - 30} marcas.\n`;
  return output;
}

// Format models
function formatModels(data) {
  let output = `🏎️ MODELOS (${data.modelos.length} encontrados):\n\n`;
  data.modelos.slice(0, 20).forEach(m => {
    output += `${String(m.codigo).padStart(5, '0')} - ${m.nome}\n`;
  });
  if (data.modelos.length > 20) {
    output += `\n... e mais ${data.modelos.length - 20} modelos.`;
  }
  return output;
}

// Format years
function formatYears(anos) {
  let output = '📅 ANOS DISPONÍVEIS:\n\n';
  anos.forEach(a => {
    output += `${a.codigo} - ${a.nome}\n`;
  });
  return output;
}

// Format search results
function formatSearch(results) {
  if (results.length === 0) {
    return 'Nenhum resultado encontrado. Tente um nome diferente.';
  }
  
  let output = `🔍 Resultados para "${results[0]?.brand || 'busca'}":\n\n`;
  results.slice(0, 10).forEach((r, i) => {
    output += `${i + 1}. ${r.model} (${r.brand})\n`;
    output += `   Use: node src/index.js preco ${r.brandId} ${r.modelId} <ano>\n\n`;
  });
  
  if (results.length > 10) {
    output += `... e mais ${results.length - 10} resultados.`;
  }
  
  return output;
}

// Main CLI
async function main() {
  const args = process.argv.slice(2);
  const command = args[0]?.toLowerCase() || 'help';
  const p1 = args[1];
  const p2 = args[2];
  const p3 = args[3];

  try {
    switch (command) {
      case 'marcas': {
        const brands = await getBrands('carros');
        console.log(formatBrands(brands));
        break;
      }
      
      case 'modelos': {
        if (!p1) {
          console.log('Uso: node src/index.js modelos <codigo_marca>');
          console.log('Exemplo: node src/index.js modelos 59');
          process.exit(1);
        }
        const data = await getModels('carros', p1);
        console.log(formatModels(data));
        break;
      }
      
      case 'anos': {
        if (!p1 || !p2) {
          console.log('Uso: node src/index.js anos <codigo_marca> <codigo_modelo>');
          console.log('Exemplo: node src/index.js anos 59 5940');
          process.exit(1);
        }
        const anos = await getYears('carros', p1, p2);
        console.log(formatYears(anos));
        break;
      }
      
      case 'preco': {
        if (!p1 || !p2 || !p3) {
          console.log('Uso: node src/index.js preco <marca> <modelo> <ano>');
          console.log('Exemplo: node src/index.js preco 59 5940 2014-3');
          process.exit(1);
        }
        const price = await getPrice('carros', p1, p2, p3);
        console.log(formatPrice(price));
        break;
      }
      
      case 'search':
      case 'buscar': {
        if (!p1) {
          console.log('Uso: node src/index.js search <nome>');
          console.log('Exemplo: node src/index.js search Hilux');
          process.exit(1);
        }
        const term = command === 'search' ? args.slice(1).join(' ') : p1;
        console.log(`🔍 Buscando "${term}"...\n`);
        const results = await searchVehicle(term);
        console.log(formatSearch(results));
        break;
      }
      
      case 'help':
      default: {
        console.log(`🚗 TABELA FIPE - Consulta de Preços
        
Comandos:
  marcas              - Listar marcas de carros
  modelos <marca>    - Listar modelos de uma marca
  anos <marca> <modelo> - Listar anos de um modelo
  preco <marca> <modelo> <ano> - Ver preço
  search <nome>      - Buscar veículo por nome

Exemplos:
  node src/index.js marcas
  node src/index.js modelos 59
  node src/index.js preco 59 5940 2014-3
  node src/index.js search Hilux
  node src/index.js search "Toyota Corolla"

Códigos de marcas comuns:
  59 - Volkswagen
  21 - Chevrolet
  23 - Ford
  33 - Fiat
  48 - Toyota
  43 - Honda
`);
      }
    }
  } catch (error) {
    console.error('Erro:', error.message);
  }
}

main();


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)