@@ -11,13 +11,14 @@ import { writeFileSync } from 'fs';
1111import {
1212 chart , transit , moon , ephemeris , version ,
1313 solarReturn , lunarReturn , synastry , progressions , ephemerisRange ,
14- composite , solarArc , horary
14+ composite , solarArc , horary , score , moonExtended , transitScan , ephemerisMulti
1515} from './lib/core.js' ;
1616import {
1717 formatChart , formatTransits , formatMoon , formatEphemeris ,
1818 formatSolarReturn , formatLunarReturn , formatSynastry ,
1919 formatProgressions , formatEphemerisRange ,
20- formatComposite , formatSolarArc , formatHorary
20+ formatComposite , formatSolarArc , formatHorary ,
21+ formatScore , formatMoonExtended , formatTransitScan , formatEphemerisMulti
2122} from './lib/format.js' ;
2223import { isError } from './types.js' ;
2324
@@ -80,7 +81,7 @@ EPHEMERIS & MOON
8081REFERENCE
8182━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8283 thoth key # full symbol reference` )
83- . version ( '0.2.16 ' ) ;
84+ . version ( '0.2.17 ' ) ;
8485
8586// Chart command
8687program
@@ -884,9 +885,180 @@ program
884885 console . log ( '' ) ;
885886 } ) ;
886887
888+ // Score command - relationship compatibility
889+ program
890+ . command ( 'score' )
891+ . description ( 'Calculate relationship compatibility score' )
892+ . requiredOption ( '--date1 <date>' , 'Person 1 birth date (YYYY-MM-DD)' )
893+ . requiredOption ( '--time1 <time>' , 'Person 1 birth time (HH:MM)' )
894+ . option ( '--city1 <city>' , 'Person 1 city' )
895+ . option ( '--nation1 <nation>' , 'Person 1 country code' , 'US' )
896+ . option ( '--lat1 <lat>' , 'Person 1 latitude' , parseFloat )
897+ . option ( '--lng1 <lng>' , 'Person 1 longitude' , parseFloat )
898+ . option ( '--name1 <name>' , 'Person 1 name' , 'Person 1' )
899+ . requiredOption ( '--date2 <date>' , 'Person 2 birth date (YYYY-MM-DD)' )
900+ . requiredOption ( '--time2 <time>' , 'Person 2 birth time (HH:MM)' )
901+ . option ( '--city2 <city>' , 'Person 2 city' )
902+ . option ( '--nation2 <nation>' , 'Person 2 country code' , 'US' )
903+ . option ( '--lat2 <lat>' , 'Person 2 latitude' , parseFloat )
904+ . option ( '--lng2 <lng>' , 'Person 2 longitude' , parseFloat )
905+ . option ( '--name2 <name>' , 'Person 2 name' , 'Person 2' )
906+ . option ( '--json' , 'Output raw JSON' )
907+ . action ( async ( options ) => {
908+ const [ year1 , month1 , day1 ] = options . date1 . split ( '-' ) . map ( Number ) ;
909+ const [ hour1 , minute1 ] = options . time1 . split ( ':' ) . map ( Number ) ;
910+ const [ year2 , month2 , day2 ] = options . date2 . split ( '-' ) . map ( Number ) ;
911+ const [ hour2 , minute2 ] = options . time2 . split ( ':' ) . map ( Number ) ;
912+
913+ const spinner = ora ( 'Calculating compatibility...' ) . start ( ) ;
914+
915+ const result = await score ( {
916+ year1, month1, day1, hour1, minute1,
917+ city1 : options . city1 , nation1 : options . nation1 ,
918+ lat1 : options . lat1 , lng1 : options . lng1 , name1 : options . name1 ,
919+ year2, month2, day2, hour2, minute2,
920+ city2 : options . city2 , nation2 : options . nation2 ,
921+ lat2 : options . lat2 , lng2 : options . lng2 , name2 : options . name2 ,
922+ } ) ;
923+
924+ spinner . stop ( ) ;
925+
926+ if ( isError ( result ) ) {
927+ console . error ( chalk . red ( 'Error: ' + result . error ) ) ;
928+ process . exit ( 1 ) ;
929+ }
930+
931+ if ( options . json ) {
932+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
933+ } else {
934+ console . log ( formatScore ( result ) ) ;
935+ }
936+ } ) ;
937+
938+ // Moon extended command
939+ program
940+ . command ( 'moon-extended' )
941+ . description ( 'Get detailed moon data with eclipses and sunrise/sunset' )
942+ . option ( '--date <date>' , 'Date (YYYY-MM-DD, default: today)' )
943+ . option ( '--lat <lat>' , 'Latitude' , parseFloat , 40.7128 )
944+ . option ( '--lng <lng>' , 'Longitude' , parseFloat , - 74.0060 )
945+ . option ( '--tz <tz>' , 'Timezone' , 'America/New_York' )
946+ . option ( '--json' , 'Output raw JSON' )
947+ . action ( async ( options ) => {
948+ let year , month , day ;
949+ if ( options . date ) {
950+ [ year , month , day ] = options . date . split ( '-' ) . map ( Number ) ;
951+ }
952+
953+ const spinner = ora ( 'Getting moon details...' ) . start ( ) ;
954+
955+ const result = await moonExtended ( {
956+ year, month, day,
957+ lat : options . lat , lng : options . lng , tz : options . tz ,
958+ } ) ;
959+
960+ spinner . stop ( ) ;
961+
962+ if ( isError ( result ) ) {
963+ console . error ( chalk . red ( 'Error: ' + result . error ) ) ;
964+ process . exit ( 1 ) ;
965+ }
966+
967+ if ( options . json ) {
968+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
969+ } else {
970+ console . log ( formatMoonExtended ( result ) ) ;
971+ }
972+ } ) ;
973+
974+ // Transit scan command
975+ program
976+ . command ( 'transit-scan' )
977+ . description ( 'Scan for transit aspects over a date range' )
978+ . requiredOption ( '--natal-date <date>' , 'Natal birth date (YYYY-MM-DD)' )
979+ . requiredOption ( '--natal-time <time>' , 'Natal birth time (HH:MM)' )
980+ . option ( '--city <city>' , 'Natal city' )
981+ . option ( '--nation <nation>' , 'Country code' , 'US' )
982+ . option ( '--lat <lat>' , 'Natal latitude' , parseFloat )
983+ . option ( '--lng <lng>' , 'Natal longitude' , parseFloat )
984+ . requiredOption ( '--from <date>' , 'Start date (YYYY-MM-DD)' )
985+ . requiredOption ( '--to <date>' , 'End date (YYYY-MM-DD)' )
986+ . option ( '--orb <orb>' , 'Aspect orb in degrees' , parseFloat , 1 )
987+ . option ( '--step <step>' , 'Step: day or week' , 'day' )
988+ . option ( '--json' , 'Output raw JSON' )
989+ . action ( async ( options ) => {
990+ const [ natalYear , natalMonth , natalDay ] = options . natalDate . split ( '-' ) . map ( Number ) ;
991+ const [ natalHour , natalMinute ] = options . natalTime . split ( ':' ) . map ( Number ) ;
992+ const [ startYear , startMonth , startDay ] = options . from . split ( '-' ) . map ( Number ) ;
993+ const [ endYear , endMonth , endDay ] = options . to . split ( '-' ) . map ( Number ) ;
994+
995+ const spinner = ora ( 'Scanning transits...' ) . start ( ) ;
996+
997+ const result = await transitScan ( {
998+ natalYear, natalMonth, natalDay, natalHour, natalMinute,
999+ natalCity : options . city , nation : options . nation ,
1000+ natalLat : options . lat , natalLng : options . lng ,
1001+ startYear, startMonth, startDay,
1002+ endYear, endMonth, endDay,
1003+ orb : options . orb , step : options . step ,
1004+ } ) ;
1005+
1006+ spinner . stop ( ) ;
1007+
1008+ if ( isError ( result ) ) {
1009+ console . error ( chalk . red ( 'Error: ' + result . error ) ) ;
1010+ process . exit ( 1 ) ;
1011+ }
1012+
1013+ if ( options . json ) {
1014+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
1015+ } else {
1016+ console . log ( formatTransitScan ( result ) ) ;
1017+ }
1018+ } ) ;
1019+
1020+ // Ephemeris multi command
1021+ program
1022+ . command ( 'ephemeris-multi' )
1023+ . description ( 'Get ephemeris for multiple bodies over a date range' )
1024+ . option ( '--bodies <bodies>' , 'Comma-separated bodies' , 'sun,moon,mercury,venus,mars,jupiter,saturn' )
1025+ . requiredOption ( '--from <date>' , 'Start date (YYYY-MM-DD)' )
1026+ . requiredOption ( '--to <date>' , 'End date (YYYY-MM-DD)' )
1027+ . option ( '--step <step>' , 'Step: hour, day, week, month' , 'day' )
1028+ . option ( '--lat <lat>' , 'Latitude' , parseFloat )
1029+ . option ( '--lng <lng>' , 'Longitude' , parseFloat )
1030+ . option ( '--json' , 'Output raw JSON' )
1031+ . action ( async ( options ) => {
1032+ const [ startYear , startMonth , startDay ] = options . from . split ( '-' ) . map ( Number ) ;
1033+ const [ endYear , endMonth , endDay ] = options . to . split ( '-' ) . map ( Number ) ;
1034+
1035+ const spinner = ora ( 'Getting ephemeris data...' ) . start ( ) ;
1036+
1037+ const result = await ephemerisMulti ( {
1038+ bodies : options . bodies ,
1039+ startYear, startMonth, startDay,
1040+ endYear, endMonth, endDay,
1041+ step : options . step ,
1042+ lat : options . lat , lng : options . lng ,
1043+ } ) ;
1044+
1045+ spinner . stop ( ) ;
1046+
1047+ if ( isError ( result ) ) {
1048+ console . error ( chalk . red ( 'Error: ' + result . error ) ) ;
1049+ process . exit ( 1 ) ;
1050+ }
1051+
1052+ if ( options . json ) {
1053+ console . log ( JSON . stringify ( result , null , 2 ) ) ;
1054+ } else {
1055+ console . log ( formatEphemerisMulti ( result ) ) ;
1056+ }
1057+ } ) ;
1058+
8871059// Banner
8881060console . log ( chalk . dim ( '' ) ) ;
889- console . log ( chalk . yellow ( ' 𓅝' ) + chalk . dim ( ' thoth-cli v0.2.16 ' ) ) ;
1061+ console . log ( chalk . yellow ( ' 𓅝' ) + chalk . dim ( ' thoth-cli v0.2.17 ' ) ) ;
8901062console . log ( chalk . dim ( '' ) ) ;
8911063
8921064program . parse ( ) ;
0 commit comments