diff --git a/.gitignore b/.gitignore index b1ec010..e9f708c 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ bun.lockb tmp/ temp/ *.tmp + +# Build notes (project planning/development notes) +build-notes/ diff --git a/cycles-week.ts b/cycles-week.ts index f2c44c5..9359660 100755 --- a/cycles-week.ts +++ b/cycles-week.ts @@ -20,6 +20,8 @@ let birthdate = ''; let name = ''; let profileId = ''; let startDate = ''; +let simpleMode = false; +let dayOnly = false; for (let i = 0; i < args.length; i++) { if ((args[i] === '--profile' || args[i] === '-p') && args[i + 1]) { @@ -34,6 +36,10 @@ for (let i = 0; i < args.length; i++) { } else if ((args[i] === '--start-date' || args[i] === '-s') && args[i + 1]) { startDate = args[i + 1]; i++; + } else if (args[i] === '--simple') { + simpleMode = true; + } else if (args[i] === '--day' || args[i] === '-d') { + dayOnly = true; } else if (args[i] === '--help' || args[i] === '-h') { console.log(` Numerology Weekly Cycles - Your personal energy forecast @@ -47,6 +53,8 @@ OPTIONS: -b, --birthdate Your birthdate (mm/dd/yyyy) [required if no profile] -n, --name Your name (for personalization) [required if no profile] -s, --start-date Start date (mm/dd/yyyy) [default: today] + -d, --day Show only today (single day output) + --simple Output clean structured format (no colors/emojis) for parsing -h, --help Show this help message EXAMPLES: @@ -138,6 +146,217 @@ function getAvoidActivities(personalDay: number): string[] { return avoid[personalDay] || avoid[personalDay % 11] || []; } +// Single day output - visual format +function outputDayVisual(todayData: any, personalYear: number, personalMonth: number, yearMeanings: Record, monthMeanings: Record) { + const { date, cycles } = todayData; + const dayName = getDayName(date); + const dayNum = date.getDate(); + const personalDay = cycles.personal.day; + + // Get meaning keywords + const meaningText = personalDayMeanings[personalDay]; + const meaningMatch = meaningText?.match(/^([^.]+)/); + const keywords = meaningMatch ? meaningMatch[1].replace(' day', '') : `Day ${personalDay}`; + + // Get activities + const bestFor = getBestActivities(personalDay); + const avoid = getAvoidActivities(personalDay); + + console.log(`\nPersonal Year ${personalYear} (${yearMeanings[personalYear]}) + Month ${personalMonth} (${monthMeanings[personalMonth]})`); + + // Add theme + if (personalYear === 33) { + console.log(`→ Theme: Master teaching year - share wisdom, serve, heal with compassion`); + } else if (personalYear === 22) { + console.log(`→ Theme: Master building year - manifest large-scale visions`); + } else if (personalYear === 11) { + console.log(`→ Theme: Inspiration year - channel higher wisdom, illuminate others`); + } else if (personalYear === 1) { + console.log(`→ Theme: Fresh starts and new beginnings - plant seeds for the next 9 years`); + } else if (personalYear === 9) { + console.log(`→ Theme: Completion and release - let go of what no longer serves`); + } else { + console.log(`→ Theme: Year ${personalYear} energy expressed through Month ${personalMonth} focus`); + } + + console.log('\n─────────────────────────────────────────────────────────'); + console.log(`${dayName} ${getMonthName(date)} ${dayNum} - Personal Day ${personalDay} (${keywords})`); + console.log(` ✅ Best for: ${bestFor.join(', ')}`); + if (avoid.length > 0) { + console.log(` ⚠️ Avoid: ${avoid.join(', ')}`); + } + console.log('─────────────────────────────────────────────────────────\n'); +} + +// Single day output - simple format (for Heka integration) +function outputDaySimple(todayData: any, personalYear: number, personalMonth: number, yearMeanings: Record, monthMeanings: Record) { + const { date, cycles } = todayData; + const dayName = date.toLocaleDateString('en-US', { weekday: 'long' }).toUpperCase(); + const dateStr = date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }); + const personalDay = cycles.personal.day; + + // Get meaning keywords + const meaningText = personalDayMeanings[personalDay]; + const meaningMatch = meaningText?.match(/^([^.]+)/); + const keywords = meaningMatch ? meaningMatch[1].replace(' day', '') : `Day ${personalDay}`; + + // Get activities + const bestFor = getBestActivities(personalDay); + const avoid = getAvoidActivities(personalDay); + + // Year theme + let yearTheme = ''; + if (personalYear === 33) { + yearTheme = 'Master teaching year - share wisdom, serve, heal with compassion'; + } else if (personalYear === 22) { + yearTheme = 'Master building year - manifest large-scale visions'; + } else if (personalYear === 11) { + yearTheme = 'Inspiration year - channel higher wisdom, illuminate others'; + } else if (personalYear === 1) { + yearTheme = 'Fresh starts and new beginnings - plant seeds for the next 9 years'; + } else if (personalYear === 9) { + yearTheme = 'Completion and release - let go of what no longer serves'; + } else { + yearTheme = `Year ${personalYear} energy expressed through Month ${personalMonth} focus`; + } + + console.log(`YEAR: Personal Year ${personalYear} (${yearMeanings[personalYear]})`); + console.log(`MONTH: Personal Month ${personalMonth} (${monthMeanings[personalMonth]})`); + console.log(`YEAR_THEME: ${yearTheme}`); + console.log(''); + console.log(`TODAY: ${dayName} ${dateStr}`); + console.log(`Personal Day ${personalDay} (${keywords})`); + console.log(`Best for: ${bestFor.join(', ')}`); + console.log(`Avoid: ${avoid.join(', ')}`); +} + +// Simple output format (no colors, emojis, or formatting) +function outputSimple(weekDays: any[], personalYear: number, personalMonth: number, yearMeanings: Record, monthMeanings: Record) { + const start = weekDays[0].date; + const end = weekDays[6].date; + + // Format dates + const startFormatted = `${getMonthName(start)} ${start.getDate()}`; + const endFormatted = `${getMonthName(end)} ${end.getDate()}, ${end.getFullYear()}`; + + console.log(`WEEK: ${startFormatted}-${endFormatted}`); + console.log(`YEAR: Personal Year ${personalYear} (${yearMeanings[personalYear]})`); + console.log(`MONTH: Personal Month ${personalMonth} (${monthMeanings[personalMonth]})`); + + // Year theme + let yearTheme = ''; + if (personalYear === 33) { + yearTheme = 'Master teaching year - share wisdom, serve, heal with compassion'; + } else if (personalYear === 22) { + yearTheme = 'Master building year - manifest large-scale visions'; + } else if (personalYear === 11) { + yearTheme = 'Inspiration year - channel higher wisdom, illuminate others'; + } else if (personalYear === 1) { + yearTheme = 'Fresh starts and new beginnings - plant seeds for the next 9 years'; + } else if (personalYear === 9) { + yearTheme = 'Completion and release - let go of what no longer serves'; + } else { + yearTheme = `Year ${personalYear} energy expressed through Month ${personalMonth} focus`; + } + console.log(`YEAR_THEME: ${yearTheme}`); + console.log(''); + console.log('DAILY_CYCLES:'); + console.log(''); + + // Output each day + for (const { date, cycles } of weekDays) { + const dayName = date.toLocaleDateString('en-US', { weekday: 'long' }).toUpperCase(); + const dateStr = date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }); + const personalDay = cycles.personal.day; + + // Get meaning keywords + const meaningText = personalDayMeanings[personalDay]; + const meaningMatch = meaningText?.match(/^([^.]+)/); + const keywords = meaningMatch ? meaningMatch[1].replace(' day', '') : `Day ${personalDay}`; + + // Get activities + const bestFor = getBestActivities(personalDay); + const avoid = getAvoidActivities(personalDay); + + console.log(`${dayName} ${dateStr}`); + console.log(`Personal Day ${personalDay} (${keywords})`); + console.log(`Best for: ${bestFor.join(', ')}`); + console.log(`Avoid: ${avoid.join(', ')}`); + console.log('---'); + } + + // Weekly theme + console.log(''); + console.log('WEEKLY_THEME:'); + if (personalYear === 33) { + console.log('Master Teacher year - you\'re called to teach, heal, and serve at a higher level. This isn\'t about personal achievement - it\'s about uplifting others through compassionate service. Abundance follows when you lead with love.'); + } else if (personalYear === 1) { + console.log('New 9-year cycle begins! Fresh starts, bold initiatives, and independent action are your themes. What you start this year echoes for 9 years.'); + } else if (personalYear === 8) { + console.log('Power and achievement year. Business opportunities, financial growth, and leadership roles are highlighted. Think big - this is your harvest time.'); + } else if (personalYear === 7) { + console.log('Introspection and spirituality year. Turn inward for wisdom. Rest, study, and spiritual practice are more important than external achievement now.'); + } else if (personalYear === 9) { + console.log('Completion year. Finish what you started, let go of what no longer serves, and prepare for a new 9-year cycle beginning next year.'); + } else { + console.log(`Year ${personalYear} energy (${yearMeanings[personalYear]}) manifesting through Month ${personalMonth}. Balance your annual theme with monthly focus for best results.`); + } + console.log(''); + + // Key opportunities + console.log('KEY_OPPORTUNITIES:'); + const opportunityDays = weekDays.filter(d => [1, 3, 8, 11, 22, 33].includes(d.cycles.personal.day)); + if (opportunityDays.length > 0) { + opportunityDays.forEach(d => { + const day = d.cycles.personal.day; + const dayName = getDayName(d.date); + const opportunities: Record = { + 1: `${dayName} (Day 1): New beginnings - launch projects, take first steps`, + 3: `${dayName} (Day 3): Expression - communicate, create, socialize`, + 8: `${dayName} (Day 8): Achievement - business moves, financial decisions`, + 11: `${dayName} (Day 11): Inspiration - teach, inspire, channel creativity`, + 22: `${dayName} (Day 22): Master building - think big, build lasting legacies`, + 33: `${dayName} (Day 33): Master teaching - heal, serve, uplift humanity` + }; + if (opportunities[day]) { + console.log(opportunities[day]); + } + }); + } else { + console.log('This week favors steady progress over dramatic breakthroughs'); + } + console.log(''); + + // Weekly advice + console.log('WEEKLY_ADVICE:'); + if (personalYear === 9) { + console.log('Finish what you started - don\'t leave loose ends'); + console.log('Let go of relationships, projects, or beliefs that no longer fit'); + console.log('Reflect on lessons from the past 9 years - wisdom awaits'); + console.log('Clear physical/mental clutter to prepare for Year 1 next year'); + } else if (personalYear === 33) { + console.log('Teach what you know - your wisdom heals others'); + console.log('Serve from overflow, not depletion (self-care first)'); + console.log('Lead with compassion, not ego or profit motive'); + console.log('Your impact ripples further than you realize'); + } else if (personalYear === 7) { + console.log('Honor your need for solitude - it\'s not selfish, it\'s necessary'); + console.log('Deep study and spiritual practice trump busy-work this year'); + console.log('Listen to your intuition - it\'s especially clear now'); + console.log('Rest isn\'t laziness - it\'s strategic preparation'); + } else if (personalYear === 8) { + console.log('Think big - this is not the year for small goals'); + console.log('Take charge of financial matters and business opportunities'); + console.log('Step into leadership roles confidently'); + console.log('Remember: power is responsibility, not domination'); + } else { + console.log('Match your activities to each day\'s energy for maximum flow'); + console.log('Rest on Day 7, launch on Day 1, express on Day 3'); + console.log('Fighting your cycles creates unnecessary resistance'); + console.log('Trust the rhythm - you\'re part of a greater pattern'); + } +} + // Main execution async function main() { // Determine start date (today by default) @@ -177,6 +396,23 @@ async function main() { 5: 'Change', 6: 'Responsibility', 7: 'Introspection', 8: 'Achievement', 9: 'Completion' }; + // Handle single-day output if --day flag is set + if (dayOnly) { + const todayData = weekDays[0]; // First day in array is "today" (or specified start date) + if (simpleMode) { + outputDaySimple(todayData, personalYear, personalMonth, yearMeanings, monthMeanings); + } else { + outputDayVisual(todayData, personalYear, personalMonth, yearMeanings, monthMeanings); + } + return; + } + + // Use simple output if flag is set + if (simpleMode) { + outputSimple(weekDays, personalYear, personalMonth, yearMeanings, monthMeanings); + return; + } + // Output header const startFormatted = `${getMonthName(start)} ${start.getDate()}`; const endDate = new Date(start); diff --git a/numerology.ts b/numerology.ts index b844114..c78205c 100755 --- a/numerology.ts +++ b/numerology.ts @@ -468,12 +468,82 @@ function formatAdvancedTerminal(additional: AdditionalNumbers, detailed: boolean return output; } +/** + * Router function - delegates to individual scripts + */ +async function routeToScript(scriptName: string, args: string[]): Promise { + const scriptPath = new URL(`./${scriptName}`, import.meta.url).pathname; + + const proc = Bun.spawn(['bun', scriptPath, ...args], { + stdout: 'inherit', + stderr: 'inherit', + stdin: 'inherit', + }); + + const exitCode = await proc.exited; + process.exit(exitCode); +} + /** * Main CLI handler */ -function main() { +async function main() { const args = process.argv.slice(2); + // Check for routing commands first (before parsing other args) + for (let i = 0; i < args.length; i++) { + // Week Cycles (handle both -c and combined flags like -cd) + if (args[i] === '--cycles-week' || args[i] === '-c' || args[i].startsWith('-c')) { + // For combined flags like -cd, expand them properly + let scriptArgs = args.filter((_, idx) => idx !== i); + + // If it's a combined flag (like -cd), extract the additional flags + if (args[i].startsWith('-c') && args[i].length > 2) { + const extraFlags = args[i].slice(2).split('').map(f => `-${f}`); + scriptArgs = [...extraFlags, ...scriptArgs]; + } + + await routeToScript('cycles-week.ts', scriptArgs); + return; + } + + // Year Ahead + if (args[i] === '--year-ahead' || args[i] === '-y') { + const scriptArgs = args.filter((_, idx) => idx !== i); + await routeToScript('year-ahead.ts', scriptArgs); + return; + } + + // Optimal Days + if (args[i] === '--optimal-days') { + const scriptArgs = args.filter((_, idx) => idx !== i); + await routeToScript('optimal-days.ts', scriptArgs); + return; + } + + // Pinnacles + if (args[i] === '--pinnacles') { + const scriptArgs = args.filter((_, idx) => idx !== i); + await routeToScript('pinnacles.ts', scriptArgs); + return; + } + + // Name Optimizer + if (args[i] === '--name-optimizer') { + const scriptArgs = args.filter((_, idx) => idx !== i); + await routeToScript('name-optimizer.ts', scriptArgs); + return; + } + + // Compatibility + if (args[i] === '--compatibility') { + const scriptArgs = args.filter((_, idx) => idx !== i); + await routeToScript('compatibility.ts', scriptArgs); + return; + } + } + + // No routing command found - proceed with core numerology calculation // Parse arguments let name = ''; let birthdate = ''; @@ -488,10 +558,10 @@ function main() { if ((args[i] === '--profile' || args[i] === '-p') && args[i + 1]) { profileId = args[i + 1]; i++; - } else if (args[i] === '--name' && args[i + 1]) { + } else if ((args[i] === '--name' || args[i] === '-n') && args[i + 1]) { name = args[i + 1]; i++; - } else if (args[i] === '--birthdate' && args[i + 1]) { + } else if ((args[i] === '--birthdate' || args[i] === '-b') && args[i + 1]) { birthdate = args[i + 1]; i++; } else if (args[i] === '--format' && args[i + 1]) { @@ -502,8 +572,6 @@ function main() { i++; } else if (args[i] === '--detailed' || args[i] === '-d') { detailed = true; - } else if (args[i] === '--cycles' || args[i] === '-c') { - showCycles = true; } else if (args[i] === '--date' && args[i + 1]) { cycleDate = args[i + 1]; i++; @@ -511,33 +579,43 @@ function main() { showAdvanced = true; } else if (args[i] === '--help' || args[i] === '-h') { console.log(` -Numerology Calculator +Numerology Calculator - Unified CLI -Usage: - bun numerology.ts --profile [options] - bun numerology.ts --name "Full Name" --birthdate "mm/dd/yyyy" [options] +CORE NUMBERS: + numerology -p Core numerology numbers + numerology -n "Name" -b "mm/dd/yyyy" Core numbers with name/birthdate -Options: - -p, --profile ID Use saved profile - --name NAME Full name (required if no profile) - --birthdate DATE Birthdate in mm/dd/yyyy format (required if no profile) - --format FORMAT Output format: terminal, markdown, json (default: terminal) - --detailed, -d Show detailed meanings (terminal format only) - --advanced, -a Show advanced numbers (Maturity, Personality, Hidden Passion, etc.) - --cycles, -c Show timing cycles (Personal & Universal Year/Month/Day) - --date DATE Date for cycle calculation (default: today, format: mm/dd/yyyy) - --help, -h Show this help message + Options: + -p, --profile ID Use saved profile + -n, --name NAME Full name (required if no profile) + -b, --birthdate DATE Birthdate in mm/dd/yyyy format (required if no profile) + -d, --detailed Show detailed meanings + -a, --advanced Show advanced numbers (Maturity, Personality, etc.) + --format FORMAT Output format: terminal, markdown, json + --date DATE Date for cycle calculation (mm/dd/yyyy) + +SPECIALIZED TOOLS: + -c, --cycles-week Weekly personal day cycles + -y, --year-ahead Full year month-by-month overview + --optimal-days Find best days for specific activities + --pinnacles Life stages & 9-year pinnacle cycles + --name-optimizer Find powerful name variations + --compatibility Compare two people's charts Examples: - # With profile - bun numerology.ts --profile john - bun numerology.ts --profile john --detailed --advanced --cycles + # Core numbers + numerology -p rob + numerology -p rob -d -a + numerology -n "John Doe" -b "5/13/1982" - # With name/birthdate - bun numerology.ts --name "John Doe" --birthdate "5/13/1982" - bun numerology.ts --name "Jane Smith" --birthdate "11/22/1990" --format markdown - bun numerology.ts --name "Bob Jones" --birthdate "3/14/1975" --format json - bun numerology.ts --name "Alice Wonder" --birthdate "7/7/1977" --detailed + # Specialized tools + numerology -c -p rob # This week's cycles + numerology -y -p rob # Year ahead + numerology --pinnacles -p rob # Life pinnacles + numerology --optimal-days -p rob --day 1 # Find all Personal Day 1s + numerology --compatibility --p1 "John:1/1/1980" --p2 "Jane:2/2/1985" + +For detailed help on each tool, use: numerology --help `); process.exit(0); } @@ -614,7 +692,7 @@ Examples: // Run if called directly if (import.meta.main) { - main(); + await main(); } export { calculate, formatTerminal, formatMarkdown, formatJson, type NumerologyResult };