#!/usr/bin/env bun import { parseArgs } from "util"; import * as math from "mathjs"; const { values, positionals } = parseArgs({ args: process.argv.slice(2), options: { mode: { type: "string", default: "mw" }, // mw (molecular weight), balance help: { type: "boolean" }, }, allowPositionals: true, }); if (values.help || positionals.length === 0) { console.log(` Chemistry Calculator Usage: skills run chemistry-calculator -- [options] Options: --mode Operation mode: mw (molecular weight), balance (balance equation) `); process.exit(0); } const input = positionals.join(" "); // Atomic weights (simplified) const atomicWeights: Record = { H: 1.008, He: 4.0026, Li: 6.94, Be: 9.0122, B: 10.81, C: 12.011, N: 14.007, O: 15.999, F: 18.998, Ne: 20.180, Na: 22.990, Mg: 24.305, Al: 26.982, Si: 28.085, P: 30.974, S: 32.06, Cl: 35.45, K: 39.098, Ar: 39.948, Ca: 40.078, Sc: 44.956, Ti: 47.867, V: 50.942, Cr: 51.996, Mn: 54.938, Fe: 55.845, Co: 58.933, Ni: 58.693, Cu: 63.546, Zn: 65.38, Ga: 69.723, Ge: 72.63, As: 74.922, Se: 78.96, Br: 79.904, Kr: 83.798, Rb: 85.468, Sr: 87.62, Y: 88.906, Zr: 91.224, Nb: 92.906, Mo: 95.95, Tc: 98, Ru: 101.07, Rh: 102.91, Pd: 106.42, Ag: 107.87, Cd: 112.41, In: 114.82, Sn: 118.71, Sb: 121.76, Te: 127.60, I: 126.90, Xe: 131.29, Cs: 132.91, Ba: 137.33, La: 138.91, // ... add more as needed }; function calculateMW(formula: string): number { const regex = /([A-Z][a-z]*)(\d*)/g; let match; let totalWeight = 0; while ((match = regex.exec(formula)) !== null) { const element = match[1]; const count = match[2] ? parseInt(match[2]) : 1; const weight = atomicWeights[element]; if (weight) { totalWeight += weight * count; } else { throw new Error(`Unknown element: ${element}`); } } return totalWeight; } async function balanceEquation(equation: string): Promise { // Using LLM for balancing as it's robust for complex equations without a heavy solver library const apiKey = process.env.OPENAI_API_KEY; if (!apiKey) { return "Error: OPENAI_API_KEY required for balancing equations."; } try { const response = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}`, }, body: JSON.stringify({ model: "gpt-4o-mini", messages: [ { role: "system", content: "You are a chemistry expert. Balance the following chemical equation. Return ONLY the balanced equation, nothing else.", }, { role: "user", content: equation, }, ], temperature: 0, }), }); const data = await response.json(); return data.choices[0].message.content.trim(); } catch (e) { return `Error balancing equation: ${e}`; } } async function main() { if (values.mode === "mw") { try { const mw = calculateMW(input); console.log(`Molecular Weight of ${input}: ${mw.toFixed(4)} g/mol`); } catch (e) { console.error(e instanceof Error ? e.message : e); } } else if (values.mode === "balance") { const balanced = await balanceEquation(input); console.log(`Balanced Equation: ${balanced}`); } } main();