thoth-cli 0.1.0
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/README.md +25 -0
- package/bin/darwin-arm64/thoth-core +0 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +298 -0
- package/dist/chunk-NYXKYHNK.js +576 -0
- package/dist/index.d.ts +191 -0
- package/dist/index.js +32 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 𓅝 thoth-cli
|
|
2
|
+
|
|
3
|
+
Hermetic astrology from the command line.
|
|
4
|
+
|
|
5
|
+
See the [main README](../../README.md) for full documentation.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g thoth-cli
|
|
11
|
+
|
|
12
|
+
thoth chart --date 1879-03-14 --time 11:30 --city "Ulm" --nation "DE" --name "Einstein"
|
|
13
|
+
thoth transit --natal-date 1879-03-14 --natal-time 11:30 --city "Ulm" --nation "DE"
|
|
14
|
+
thoth moon
|
|
15
|
+
thoth ephemeris --body pluto
|
|
16
|
+
thoth key
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Privacy
|
|
20
|
+
|
|
21
|
+
No data collection. All calculations run locally.
|
|
22
|
+
|
|
23
|
+
## License
|
|
24
|
+
|
|
25
|
+
MIT
|
|
File without changes
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
chart,
|
|
4
|
+
ephemeris,
|
|
5
|
+
formatChart,
|
|
6
|
+
formatEphemeris,
|
|
7
|
+
formatMoon,
|
|
8
|
+
formatTransits,
|
|
9
|
+
isError,
|
|
10
|
+
moon,
|
|
11
|
+
transit,
|
|
12
|
+
version
|
|
13
|
+
} from "./chunk-NYXKYHNK.js";
|
|
14
|
+
|
|
15
|
+
// src/bin.ts
|
|
16
|
+
import { Command } from "commander";
|
|
17
|
+
import chalk from "chalk";
|
|
18
|
+
import ora from "ora";
|
|
19
|
+
var program = new Command();
|
|
20
|
+
program.name("thoth").description(`\u{1315D} Astrological calculations from the command line
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
thoth chart --date 1991-07-08 --time 14:06 --city "New York"
|
|
24
|
+
thoth transit --natal-date 1991-07-08 --natal-time 14:06 --city "New York"
|
|
25
|
+
thoth moon
|
|
26
|
+
thoth ephemeris --body pluto`).version("0.1.0");
|
|
27
|
+
program.command("chart").description(`Calculate a natal chart
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
thoth chart --date 1991-07-08 --time 14:06 --city "New York" --name "AKLO"
|
|
31
|
+
thoth chart --date 1986-07-29 --time 12:00 --lat 40.7128 --lng -74.0060`).requiredOption("--date <date>", "Birth date (YYYY-MM-DD)").requiredOption("--time <time>", "Birth time (HH:MM)").option("--lat <lat>", "Latitude", parseFloat).option("--lng <lng>", "Longitude", parseFloat).option("--city <city>", 'City name (e.g., "New York")').option("--nation <nation>", "Country code (e.g., US, UK)", "US").option("--name <name>", "Name", "Subject").option("--json", "Output raw JSON").action(async (options) => {
|
|
32
|
+
if (!options.city && (!options.lat || !options.lng)) {
|
|
33
|
+
console.error(chalk.red("Error: Must provide either --city or both --lat and --lng"));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const spinner = ora("Calculating chart...").start();
|
|
37
|
+
const [year, month, day] = options.date.split("-").map(Number);
|
|
38
|
+
const [hour, minute] = options.time.split(":").map(Number);
|
|
39
|
+
const result = await chart({
|
|
40
|
+
year,
|
|
41
|
+
month,
|
|
42
|
+
day,
|
|
43
|
+
hour,
|
|
44
|
+
minute,
|
|
45
|
+
lat: options.lat,
|
|
46
|
+
lng: options.lng,
|
|
47
|
+
city: options.city,
|
|
48
|
+
nation: options.nation,
|
|
49
|
+
name: options.name
|
|
50
|
+
});
|
|
51
|
+
spinner.stop();
|
|
52
|
+
if (isError(result)) {
|
|
53
|
+
console.error(chalk.red(`Error: ${result.error}`));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
if (options.json) {
|
|
57
|
+
console.log(JSON.stringify(result, null, 2));
|
|
58
|
+
} else {
|
|
59
|
+
console.log(formatChart(result));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
program.command("transit").description(`Calculate transits to a natal chart
|
|
63
|
+
|
|
64
|
+
Examples:
|
|
65
|
+
thoth transit --natal-date 1991-07-08 --natal-time 14:06 --city "New York"
|
|
66
|
+
thoth transit --natal-date 1991-07-08 --natal-time 14:06 --city "New York" --orb 1`).requiredOption("--natal-date <date>", "Natal date (YYYY-MM-DD)").requiredOption("--natal-time <time>", "Natal time (HH:MM)").option("--lat <lat>", "Latitude", parseFloat).option("--lng <lng>", "Longitude", parseFloat).option("--city <city>", 'City name (e.g., "New York")').option("--nation <nation>", "Country code (e.g., US, UK)", "US").option("--transit-date <date>", "Transit date (YYYY-MM-DD, default: today)").option("--orb <degrees>", "Orb in degrees", parseFloat, 3).option("--json", "Output raw JSON").action(async (options) => {
|
|
67
|
+
if (!options.city && (!options.lat || !options.lng)) {
|
|
68
|
+
console.error(chalk.red("Error: Must provide either --city or both --lat and --lng"));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
const spinner = ora("Calculating transits...").start();
|
|
72
|
+
const [natalYear, natalMonth, natalDay] = options.natalDate.split("-").map(Number);
|
|
73
|
+
const [natalHour, natalMinute] = options.natalTime.split(":").map(Number);
|
|
74
|
+
let transitYear, transitMonth, transitDay;
|
|
75
|
+
if (options.transitDate) {
|
|
76
|
+
[transitYear, transitMonth, transitDay] = options.transitDate.split("-").map(Number);
|
|
77
|
+
}
|
|
78
|
+
const result = await transit({
|
|
79
|
+
natalYear,
|
|
80
|
+
natalMonth,
|
|
81
|
+
natalDay,
|
|
82
|
+
natalHour,
|
|
83
|
+
natalMinute,
|
|
84
|
+
natalLat: options.lat,
|
|
85
|
+
natalLng: options.lng,
|
|
86
|
+
natalCity: options.city,
|
|
87
|
+
nation: options.nation,
|
|
88
|
+
transitYear,
|
|
89
|
+
transitMonth,
|
|
90
|
+
transitDay,
|
|
91
|
+
orb: options.orb
|
|
92
|
+
});
|
|
93
|
+
spinner.stop();
|
|
94
|
+
if (isError(result)) {
|
|
95
|
+
console.error(chalk.red(`Error: ${result.error}`));
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
if (options.json) {
|
|
99
|
+
console.log(JSON.stringify(result, null, 2));
|
|
100
|
+
} else {
|
|
101
|
+
console.log(formatTransits(result));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
program.command("moon").description("Get current moon phase and position").option("--date <date>", "Date (YYYY-MM-DD, default: today)").option("--lat <lat>", "Latitude", parseFloat, 40.7128).option("--lng <lng>", "Longitude", parseFloat, -74.006).option("--json", "Output raw JSON").action(async (options) => {
|
|
105
|
+
const spinner = ora("Getting moon phase...").start();
|
|
106
|
+
let year, month, day;
|
|
107
|
+
if (options.date) {
|
|
108
|
+
[year, month, day] = options.date.split("-").map(Number);
|
|
109
|
+
}
|
|
110
|
+
const result = await moon({
|
|
111
|
+
year,
|
|
112
|
+
month,
|
|
113
|
+
day,
|
|
114
|
+
lat: options.lat,
|
|
115
|
+
lng: options.lng
|
|
116
|
+
});
|
|
117
|
+
spinner.stop();
|
|
118
|
+
if (isError(result)) {
|
|
119
|
+
console.error(chalk.red(`Error: ${result.error}`));
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
if (options.json) {
|
|
123
|
+
console.log(JSON.stringify(result, null, 2));
|
|
124
|
+
} else {
|
|
125
|
+
console.log(formatMoon(result));
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
program.command("ephemeris").description("Get ephemeris position for a celestial body").requiredOption("--body <body>", "Celestial body (sun, moon, mars, etc.)").option("--date <date>", "Date (YYYY-MM-DD, default: today)").option("--json", "Output raw JSON").action(async (options) => {
|
|
129
|
+
const spinner = ora(`Getting ${options.body} position...`).start();
|
|
130
|
+
let year, month, day;
|
|
131
|
+
if (options.date) {
|
|
132
|
+
[year, month, day] = options.date.split("-").map(Number);
|
|
133
|
+
}
|
|
134
|
+
const result = await ephemeris({
|
|
135
|
+
body: options.body,
|
|
136
|
+
year,
|
|
137
|
+
month,
|
|
138
|
+
day
|
|
139
|
+
});
|
|
140
|
+
spinner.stop();
|
|
141
|
+
if (isError(result)) {
|
|
142
|
+
console.error(chalk.red(`Error: ${result.error}`));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
if (options.json) {
|
|
146
|
+
console.log(JSON.stringify(result, null, 2));
|
|
147
|
+
} else {
|
|
148
|
+
console.log(formatEphemeris(result));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
program.command("core-version").description("Show thoth-core version").action(async () => {
|
|
152
|
+
const result = await version();
|
|
153
|
+
if (isError(result)) {
|
|
154
|
+
console.error(chalk.red(`Error: ${result.error}`));
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
console.log(chalk.cyan(`thoth-core v${result.version}`));
|
|
158
|
+
});
|
|
159
|
+
program.command("key").description("Symbol reference guide").action(() => {
|
|
160
|
+
const sun = chalk.hex("#FFD700");
|
|
161
|
+
const moon2 = chalk.hex("#C0C0C0");
|
|
162
|
+
const mercury = chalk.hex("#FF8C00");
|
|
163
|
+
const venus = chalk.hex("#00FF7F");
|
|
164
|
+
const mars = chalk.hex("#FF0000");
|
|
165
|
+
const jupiter = chalk.hex("#4169E1");
|
|
166
|
+
const saturn = chalk.hex("#4B0082");
|
|
167
|
+
const uranus = chalk.hex("#00FFFF");
|
|
168
|
+
const neptune = chalk.hex("#20B2AA");
|
|
169
|
+
const pluto = chalk.hex("#8B0000");
|
|
170
|
+
const chiron = chalk.hex("#9932CC");
|
|
171
|
+
const lilith = chalk.hex("#800020");
|
|
172
|
+
const northNode = chalk.hex("#FFD700");
|
|
173
|
+
const southNode = chalk.hex("#C0C0C0");
|
|
174
|
+
console.log(chalk.bold.white("\n\u{1315D} THOTH KEY \u2014 Complete Reference\n"));
|
|
175
|
+
console.log(chalk.bold.cyan("\u2550\u2550 PLANETS \u2550\u2550"));
|
|
176
|
+
console.log(` ${sun("\u2609 Sun")} Identity, vitality, ego, life force`);
|
|
177
|
+
console.log(` ${chalk.dim("Rules:")} ${sun("Leo")} ${chalk.dim("Sephira:")} Tiphareth`);
|
|
178
|
+
console.log(` ${moon2("\u263D Moon")} Emotions, instincts, the unconscious, mother`);
|
|
179
|
+
console.log(` ${chalk.dim("Rules:")} ${moon2("Cancer")} ${chalk.dim("Sephira:")} Yesod`);
|
|
180
|
+
console.log(` ${mercury("\u263F Mercury")} Mind, communication, learning, commerce`);
|
|
181
|
+
console.log(` ${chalk.dim("Rules:")} ${mercury("Gemini, Virgo")} ${chalk.dim("Sephira:")} Hod`);
|
|
182
|
+
console.log(` ${venus("\u2640 Venus")} Love, beauty, values, attraction, harmony`);
|
|
183
|
+
console.log(` ${chalk.dim("Rules:")} ${venus("Taurus, Libra")} ${chalk.dim("Sephira:")} Netzach`);
|
|
184
|
+
console.log(` ${mars("\u2642 Mars")} Action, desire, aggression, courage, drive`);
|
|
185
|
+
console.log(` ${chalk.dim("Rules:")} ${mars("Aries")} ${chalk.dim("Sephira:")} Geburah`);
|
|
186
|
+
console.log(` ${jupiter("\u2643 Jupiter")} Expansion, luck, wisdom, abundance, faith`);
|
|
187
|
+
console.log(` ${chalk.dim("Rules:")} ${jupiter("Sagittarius")} ${chalk.dim("Sephira:")} Chesed`);
|
|
188
|
+
console.log(` ${saturn("\u2644 Saturn")} Structure, limits, time, karma, discipline`);
|
|
189
|
+
console.log(` ${chalk.dim("Rules:")} ${saturn("Capricorn")} ${chalk.dim("Sephira:")} Binah`);
|
|
190
|
+
console.log(` ${uranus("\u2645 Uranus")} Revolution, awakening, innovation, freedom`);
|
|
191
|
+
console.log(` ${chalk.dim("Rules:")} ${uranus("Aquarius")} ${chalk.dim("Sephira:")} Chokmah`);
|
|
192
|
+
console.log(` ${neptune("\u2646 Neptune")} Dreams, illusion, spirituality, dissolution`);
|
|
193
|
+
console.log(` ${chalk.dim("Rules:")} ${neptune("Pisces")}`);
|
|
194
|
+
console.log(` ${pluto("\u2647 Pluto")} Transformation, death/rebirth, power, shadow`);
|
|
195
|
+
console.log(` ${chalk.dim("Rules:")} ${pluto("Scorpio")}`);
|
|
196
|
+
console.log("");
|
|
197
|
+
console.log(chalk.bold.cyan("\u2550\u2550 POINTS \u2550\u2550"));
|
|
198
|
+
console.log(` ${chiron("\u26B7 Chiron")} The wounded healer. Core wound & gift of healing.`);
|
|
199
|
+
console.log(` ${lilith("\u26B8 Lilith")} Black Moon. Primal feminine, shadow, rejection.`);
|
|
200
|
+
console.log(` ${northNode("\u260A North Node")} Soul's direction. Growth edge. Future karma.`);
|
|
201
|
+
console.log(` ${southNode("\u260B South Node")} Past life gifts. Comfort zone. Past karma.`);
|
|
202
|
+
console.log("");
|
|
203
|
+
console.log(chalk.bold.cyan("\u2550\u2550 ZODIAC SIGNS \u2550\u2550"));
|
|
204
|
+
console.log(` ${mars("\u2648 Aries")} ${chalk.dim("Cardinal Fire")} Initiative, courage, impatience`);
|
|
205
|
+
console.log(` ${chalk.dim("Ruler:")} ${mars("Mars")} ${chalk.dim('"I AM"')}`);
|
|
206
|
+
console.log(` ${venus("\u2649 Taurus")} ${chalk.dim("Fixed Earth")} Stability, sensuality, stubborn`);
|
|
207
|
+
console.log(` ${chalk.dim("Ruler:")} ${venus("Venus")} ${chalk.dim('"I HAVE"')}`);
|
|
208
|
+
console.log(` ${mercury("\u264A Gemini")} ${chalk.dim("Mutable Air")} Curiosity, duality, scattered`);
|
|
209
|
+
console.log(` ${chalk.dim("Ruler:")} ${mercury("Mercury")} ${chalk.dim('"I THINK"')}`);
|
|
210
|
+
console.log(` ${moon2("\u264B Cancer")} ${chalk.dim("Cardinal Water")} Nurturing, protective, moody`);
|
|
211
|
+
console.log(` ${chalk.dim("Ruler:")} ${moon2("Moon")} ${chalk.dim('"I FEEL"')}`);
|
|
212
|
+
console.log(` ${sun("\u264C Leo")} ${chalk.dim("Fixed Fire")} Creative, proud, dramatic`);
|
|
213
|
+
console.log(` ${chalk.dim("Ruler:")} ${sun("Sun")} ${chalk.dim('"I WILL"')}`);
|
|
214
|
+
console.log(` ${mercury("\u264D Virgo")} ${chalk.dim("Mutable Earth")} Analytical, service, critical`);
|
|
215
|
+
console.log(` ${chalk.dim("Ruler:")} ${mercury("Mercury")} ${chalk.dim('"I ANALYZE"')}`);
|
|
216
|
+
console.log(` ${venus("\u264E Libra")} ${chalk.dim("Cardinal Air")} Balance, partnership, indecisive`);
|
|
217
|
+
console.log(` ${chalk.dim("Ruler:")} ${venus("Venus")} ${chalk.dim('"I BALANCE"')}`);
|
|
218
|
+
console.log(` ${pluto("\u264F Scorpio")} ${chalk.dim("Fixed Water")} Intensity, depth, secretive`);
|
|
219
|
+
console.log(` ${chalk.dim("Ruler:")} ${pluto("Pluto")} ${chalk.dim('"I DESIRE"')}`);
|
|
220
|
+
console.log(` ${jupiter("\u2650 Sagittarius")} ${chalk.dim("Mutable Fire")} Adventure, truth, reckless`);
|
|
221
|
+
console.log(` ${chalk.dim("Ruler:")} ${jupiter("Jupiter")} ${chalk.dim('"I SEE"')}`);
|
|
222
|
+
console.log(` ${saturn("\u2651 Capricorn")} ${chalk.dim("Cardinal Earth")} Ambition, mastery, cold`);
|
|
223
|
+
console.log(` ${chalk.dim("Ruler:")} ${saturn("Saturn")} ${chalk.dim('"I USE"')}`);
|
|
224
|
+
console.log(` ${uranus("\u2652 Aquarius")} ${chalk.dim("Fixed Air")} Humanitarian, eccentric, detached`);
|
|
225
|
+
console.log(` ${chalk.dim("Ruler:")} ${uranus("Uranus")} ${chalk.dim('"I KNOW"')}`);
|
|
226
|
+
console.log(` ${neptune("\u2653 Pisces")} ${chalk.dim("Mutable Water")} Compassion, dreams, escapist`);
|
|
227
|
+
console.log(` ${chalk.dim("Ruler:")} ${neptune("Neptune")} ${chalk.dim('"I BELIEVE"')}`);
|
|
228
|
+
console.log("");
|
|
229
|
+
console.log(chalk.bold.cyan("\u2550\u2550 HOUSES \u2550\u2550"));
|
|
230
|
+
console.log(` ${chalk.bold("1st House")} ${mars("Ascendant")} Self, identity, appearance, first impressions`);
|
|
231
|
+
console.log(` ${chalk.bold("2nd House")} Money, possessions, values, self-worth`);
|
|
232
|
+
console.log(` ${chalk.bold("3rd House")} Communication, siblings, short travel, learning`);
|
|
233
|
+
console.log(` ${chalk.bold("4th House")} ${saturn("IC")} Home, family, roots, private self, mother`);
|
|
234
|
+
console.log(` ${chalk.bold("5th House")} Creativity, romance, children, pleasure, play`);
|
|
235
|
+
console.log(` ${chalk.bold("6th House")} Health, work, service, daily routines, pets`);
|
|
236
|
+
console.log(` ${chalk.bold("7th House")} ${chalk.white("Descendant")} Partnerships, marriage, open enemies, others`);
|
|
237
|
+
console.log(` ${chalk.bold("8th House")} Death, sex, shared resources, transformation`);
|
|
238
|
+
console.log(` ${chalk.bold("9th House")} Philosophy, long travel, higher education, beliefs`);
|
|
239
|
+
console.log(` ${chalk.bold("10th House")} ${sun("MC")} Career, reputation, public self, father`);
|
|
240
|
+
console.log(` ${chalk.bold("11th House")} Friends, groups, hopes, wishes, humanity`);
|
|
241
|
+
console.log(` ${chalk.bold("12th House")} Unconscious, isolation, secrets, karma, dreams`);
|
|
242
|
+
console.log("");
|
|
243
|
+
console.log(chalk.bold.cyan("\u2550\u2550 ASPECTS \u2550\u2550"));
|
|
244
|
+
console.log(` ${sun("\u260C Conjunction")} 0\xB0 Fusion, intensification, new cycle`);
|
|
245
|
+
console.log(` ${chalk.dim("Sephira: Tiphareth (Sun) \u2014 creative union")}`);
|
|
246
|
+
console.log(` ${moon2("\u260D Opposition")} 180\xB0 Awareness, tension, projection`);
|
|
247
|
+
console.log(` ${chalk.dim("Sephira: Yesod (Moon) \u2014 polarity, reflection")}`);
|
|
248
|
+
console.log(` ${jupiter("\u25B3 Trine")} 120\xB0 Harmony, ease, natural talent`);
|
|
249
|
+
console.log(` ${chalk.dim("Sephira: Chesed (Jupiter) \u2014 grace, flow")}`);
|
|
250
|
+
console.log(` ${mars("\u25A1 Square")} 90\xB0 Friction, challenge, forced growth`);
|
|
251
|
+
console.log(` ${chalk.dim("Sephira: Geburah (Mars) \u2014 strength through struggle")}`);
|
|
252
|
+
console.log(` ${venus("\u26B9 Sextile")} 60\xB0 Opportunity, cooperation, ease`);
|
|
253
|
+
console.log(` ${chalk.dim("Sephira: Netzach (Venus) \u2014 gentle harmony")}`);
|
|
254
|
+
console.log(` ${mercury("\u235F Quintile")} 72\xB0 Creativity, talent, genius`);
|
|
255
|
+
console.log(` ${chalk.dim("Sephira: Hod (Mercury) \u2014 mental brilliance")}`);
|
|
256
|
+
console.log(` ${uranus("\u26BB Quincunx")} 150\xB0 Adjustment, awkwardness, recalibration`);
|
|
257
|
+
console.log("");
|
|
258
|
+
console.log(chalk.bold.cyan("\u2550\u2550 ELEMENTS \u2550\u2550"));
|
|
259
|
+
console.log(` ${mars("\u{1F702} Fire")} ${mars("Aries, Leo, Sagittarius")}`);
|
|
260
|
+
console.log(` Spirit, will, action, enthusiasm`);
|
|
261
|
+
console.log(` ${chalk.dim("Hot & Dry \u2014 Choleric \u2014 Intuitive function")}`);
|
|
262
|
+
console.log(` ${venus("\u{1F703} Earth")} ${venus("Taurus, Virgo, Capricorn")}`);
|
|
263
|
+
console.log(` Matter, stability, practicality, form`);
|
|
264
|
+
console.log(` ${chalk.dim("Cold & Dry \u2014 Melancholic \u2014 Sensation function")}`);
|
|
265
|
+
console.log(` ${mercury("\u{1F701} Air")} ${mercury("Gemini, Libra, Aquarius")}`);
|
|
266
|
+
console.log(` Mind, communication, connection, ideas`);
|
|
267
|
+
console.log(` ${chalk.dim("Hot & Wet \u2014 Sanguine \u2014 Thinking function")}`);
|
|
268
|
+
console.log(` ${moon2("\u{1F704} Water")} ${moon2("Cancer")}, ${pluto("Scorpio")}, ${neptune("Pisces")}`);
|
|
269
|
+
console.log(` Emotion, intuition, the unconscious, soul`);
|
|
270
|
+
console.log(` ${chalk.dim("Cold & Wet \u2014 Phlegmatic \u2014 Feeling function")}`);
|
|
271
|
+
console.log("");
|
|
272
|
+
console.log(chalk.bold.cyan("\u2550\u2550 MODALITIES \u2550\u2550"));
|
|
273
|
+
console.log(` ${chalk.bold("Cardinal")} ${mars("Aries")}, ${moon2("Cancer")}, ${venus("Libra")}, ${saturn("Capricorn")}`);
|
|
274
|
+
console.log(` Initiating, leadership, action`);
|
|
275
|
+
console.log(` ${chalk.dim('The spark. Begins seasons. "I start."')}`);
|
|
276
|
+
console.log(` ${chalk.bold("Fixed")} ${venus("Taurus")}, ${sun("Leo")}, ${pluto("Scorpio")}, ${uranus("Aquarius")}`);
|
|
277
|
+
console.log(` Stabilizing, persistence, stubborn`);
|
|
278
|
+
console.log(` ${chalk.dim('The sustainer. Mid-season. "I maintain."')}`);
|
|
279
|
+
console.log(` ${chalk.bold("Mutable")} ${mercury("Gemini")}, ${mercury("Virgo")}, ${jupiter("Sagittarius")}, ${neptune("Pisces")}`);
|
|
280
|
+
console.log(` Adapting, flexible, changeable`);
|
|
281
|
+
console.log(` ${chalk.dim('The dissolver. End of season. "I change."')}`);
|
|
282
|
+
console.log("");
|
|
283
|
+
console.log(chalk.bold.cyan("\u2550\u2550 OTHER \u2550\u2550"));
|
|
284
|
+
console.log(` ${mars("\u211E")} Retrograde Planet appears to move backward. Internalized energy.`);
|
|
285
|
+
console.log(` H House Area of life. e.g., 4H = home, roots, private self`);
|
|
286
|
+
console.log(` \u2192 Flow Direction. e.g., 2H\u21924H (transit house \u2192 natal house)`);
|
|
287
|
+
console.log("");
|
|
288
|
+
console.log(chalk.bold.cyan("\u2550\u2550 DIGNITIES \u2550\u2550"));
|
|
289
|
+
console.log(` ${chalk.bold("Domicile")} Planet in sign it rules. Full power. ${chalk.dim("e.g., Mars in Aries")}`);
|
|
290
|
+
console.log(` ${chalk.bold("Exaltation")} Planet in sign of peak expression. ${chalk.dim("e.g., Sun in Aries")}`);
|
|
291
|
+
console.log(` ${chalk.bold("Detriment")} Planet opposite its home. Challenged. ${chalk.dim("e.g., Mars in Libra")}`);
|
|
292
|
+
console.log(` ${chalk.bold("Fall")} Planet opposite exaltation. Weakened. ${chalk.dim("e.g., Sun in Libra")}`);
|
|
293
|
+
console.log("");
|
|
294
|
+
});
|
|
295
|
+
console.log(chalk.dim(""));
|
|
296
|
+
console.log(chalk.yellow(" \u{1315D}") + chalk.dim(" thoth-cli"));
|
|
297
|
+
console.log(chalk.dim(""));
|
|
298
|
+
program.parse();
|
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
// src/lib/core.ts
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
|
|
4
|
+
// src/lib/binary.ts
|
|
5
|
+
import { platform, arch } from "os";
|
|
6
|
+
import { join, dirname } from "path";
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
function getPlatformKey() {
|
|
11
|
+
const p = platform();
|
|
12
|
+
const a = arch();
|
|
13
|
+
const platformMap = {
|
|
14
|
+
"darwin": "darwin",
|
|
15
|
+
"linux": "linux",
|
|
16
|
+
"win32": "win32"
|
|
17
|
+
};
|
|
18
|
+
const archMap = {
|
|
19
|
+
"x64": "x64",
|
|
20
|
+
"arm64": "arm64"
|
|
21
|
+
};
|
|
22
|
+
const mappedPlatform = platformMap[p];
|
|
23
|
+
const mappedArch = archMap[a];
|
|
24
|
+
if (!mappedPlatform || !mappedArch) {
|
|
25
|
+
throw new Error(`Unsupported platform: ${p}-${a}`);
|
|
26
|
+
}
|
|
27
|
+
return `${mappedPlatform}-${mappedArch}`;
|
|
28
|
+
}
|
|
29
|
+
function getBinaryName() {
|
|
30
|
+
const p = platform();
|
|
31
|
+
return p === "win32" ? "thoth-core.exe" : "thoth-core";
|
|
32
|
+
}
|
|
33
|
+
function getBinaryPath() {
|
|
34
|
+
const platformKey = getPlatformKey();
|
|
35
|
+
const binaryName = getBinaryName();
|
|
36
|
+
const possiblePaths = [
|
|
37
|
+
// Installed via npm (production)
|
|
38
|
+
join(__dirname, "..", "..", "bin", platformKey, binaryName),
|
|
39
|
+
// Development (monorepo)
|
|
40
|
+
join(__dirname, "..", "..", "..", "..", "bin", platformKey, binaryName),
|
|
41
|
+
// Local development
|
|
42
|
+
join(__dirname, "..", "..", "bin", binaryName)
|
|
43
|
+
];
|
|
44
|
+
for (const p of possiblePaths) {
|
|
45
|
+
if (existsSync(p)) {
|
|
46
|
+
return p;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return "python";
|
|
50
|
+
}
|
|
51
|
+
function getCommand() {
|
|
52
|
+
const binaryPath = getBinaryPath();
|
|
53
|
+
if (binaryPath === "python") {
|
|
54
|
+
return {
|
|
55
|
+
command: "python3",
|
|
56
|
+
args: ["-m", "thoth_core.cli"]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
command: binaryPath,
|
|
61
|
+
args: []
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/lib/core.ts
|
|
66
|
+
async function execute(subcommand, args) {
|
|
67
|
+
const { command, args: baseArgs } = getCommand();
|
|
68
|
+
try {
|
|
69
|
+
const result = await execa(command, [...baseArgs, subcommand, ...args], {
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
reject: false
|
|
72
|
+
});
|
|
73
|
+
if (result.exitCode !== 0) {
|
|
74
|
+
const error = result.stderr || result.stdout;
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(error);
|
|
77
|
+
} catch {
|
|
78
|
+
return { error: error || "Unknown error" };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return JSON.parse(result.stdout);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return { error: err instanceof Error ? err.message : "Unknown error" };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function chart(options) {
|
|
87
|
+
const args = [
|
|
88
|
+
"--year",
|
|
89
|
+
String(options.year),
|
|
90
|
+
"--month",
|
|
91
|
+
String(options.month),
|
|
92
|
+
"--day",
|
|
93
|
+
String(options.day),
|
|
94
|
+
"--hour",
|
|
95
|
+
String(options.hour ?? 12),
|
|
96
|
+
"--minute",
|
|
97
|
+
String(options.minute ?? 0),
|
|
98
|
+
"--name",
|
|
99
|
+
options.name ?? "Subject"
|
|
100
|
+
];
|
|
101
|
+
if (options.city) {
|
|
102
|
+
args.push("--city", options.city);
|
|
103
|
+
args.push("--nation", options.nation ?? "US");
|
|
104
|
+
} else if (options.lat !== void 0 && options.lng !== void 0) {
|
|
105
|
+
args.push("--lat", String(options.lat));
|
|
106
|
+
args.push("--lng", String(options.lng));
|
|
107
|
+
}
|
|
108
|
+
return execute("chart", args);
|
|
109
|
+
}
|
|
110
|
+
async function transit(options) {
|
|
111
|
+
const args = [
|
|
112
|
+
"--natal-year",
|
|
113
|
+
String(options.natalYear),
|
|
114
|
+
"--natal-month",
|
|
115
|
+
String(options.natalMonth),
|
|
116
|
+
"--natal-day",
|
|
117
|
+
String(options.natalDay),
|
|
118
|
+
"--natal-hour",
|
|
119
|
+
String(options.natalHour ?? 12),
|
|
120
|
+
"--natal-minute",
|
|
121
|
+
String(options.natalMinute ?? 0),
|
|
122
|
+
"--orb",
|
|
123
|
+
String(options.orb ?? 3)
|
|
124
|
+
];
|
|
125
|
+
if (options.natalCity) {
|
|
126
|
+
args.push("--natal-city", options.natalCity);
|
|
127
|
+
args.push("--nation", options.nation ?? "US");
|
|
128
|
+
} else if (options.natalLat !== void 0 && options.natalLng !== void 0) {
|
|
129
|
+
args.push("--natal-lat", String(options.natalLat));
|
|
130
|
+
args.push("--natal-lng", String(options.natalLng));
|
|
131
|
+
}
|
|
132
|
+
if (options.transitYear) args.push("--transit-year", String(options.transitYear));
|
|
133
|
+
if (options.transitMonth) args.push("--transit-month", String(options.transitMonth));
|
|
134
|
+
if (options.transitDay) args.push("--transit-day", String(options.transitDay));
|
|
135
|
+
return execute("transit", args);
|
|
136
|
+
}
|
|
137
|
+
async function moon(options = {}) {
|
|
138
|
+
const args = [];
|
|
139
|
+
if (options.year) args.push("--year", String(options.year));
|
|
140
|
+
if (options.month) args.push("--month", String(options.month));
|
|
141
|
+
if (options.day) args.push("--day", String(options.day));
|
|
142
|
+
if (options.lat) args.push("--lat", String(options.lat));
|
|
143
|
+
if (options.lng) args.push("--lng", String(options.lng));
|
|
144
|
+
return execute("moon", args);
|
|
145
|
+
}
|
|
146
|
+
async function ephemeris(options) {
|
|
147
|
+
const args = ["--body", options.body];
|
|
148
|
+
if (options.year) args.push("--year", String(options.year));
|
|
149
|
+
if (options.month) args.push("--month", String(options.month));
|
|
150
|
+
if (options.day) args.push("--day", String(options.day));
|
|
151
|
+
return execute("ephemeris", args);
|
|
152
|
+
}
|
|
153
|
+
async function version() {
|
|
154
|
+
return execute("version", []);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/lib/format.ts
|
|
158
|
+
import chalk from "chalk";
|
|
159
|
+
var COLORS = {
|
|
160
|
+
// Planets (Sephirotic correspondences)
|
|
161
|
+
sun: chalk.hex("#FFD700"),
|
|
162
|
+
// Gold - Tiphareth
|
|
163
|
+
moon: chalk.hex("#C0C0C0"),
|
|
164
|
+
// Silver - Yesod
|
|
165
|
+
mercury: chalk.hex("#FF8C00"),
|
|
166
|
+
// Orange - Hod
|
|
167
|
+
venus: chalk.hex("#00FF7F"),
|
|
168
|
+
// Green - Netzach
|
|
169
|
+
mars: chalk.hex("#FF0000"),
|
|
170
|
+
// Red - Geburah
|
|
171
|
+
jupiter: chalk.hex("#4169E1"),
|
|
172
|
+
// Royal Blue - Chesed
|
|
173
|
+
saturn: chalk.hex("#4B0082"),
|
|
174
|
+
// Indigo - Binah
|
|
175
|
+
uranus: chalk.hex("#00FFFF"),
|
|
176
|
+
// Electric Cyan - Chokmah
|
|
177
|
+
neptune: chalk.hex("#20B2AA"),
|
|
178
|
+
// Sea Green
|
|
179
|
+
pluto: chalk.hex("#8B0000"),
|
|
180
|
+
// Dark Red
|
|
181
|
+
chiron: chalk.hex("#9932CC"),
|
|
182
|
+
// Purple - wounded healer
|
|
183
|
+
lilith: chalk.hex("#800020"),
|
|
184
|
+
// Burgundy - primal
|
|
185
|
+
northNode: chalk.hex("#FFD700"),
|
|
186
|
+
// Gold
|
|
187
|
+
southNode: chalk.hex("#C0C0C0")
|
|
188
|
+
// Silver
|
|
189
|
+
};
|
|
190
|
+
function getPlanetColor(name) {
|
|
191
|
+
const colorMap = {
|
|
192
|
+
"sun": COLORS.sun,
|
|
193
|
+
"moon": COLORS.moon,
|
|
194
|
+
"mercury": COLORS.mercury,
|
|
195
|
+
"venus": COLORS.venus,
|
|
196
|
+
"mars": COLORS.mars,
|
|
197
|
+
"jupiter": COLORS.jupiter,
|
|
198
|
+
"saturn": COLORS.saturn,
|
|
199
|
+
"uranus": COLORS.uranus,
|
|
200
|
+
"neptune": COLORS.neptune,
|
|
201
|
+
"pluto": COLORS.pluto,
|
|
202
|
+
"chiron": COLORS.chiron,
|
|
203
|
+
"mean_lilith": COLORS.lilith,
|
|
204
|
+
"lilith": COLORS.lilith,
|
|
205
|
+
"true_north_lunar_node": COLORS.northNode,
|
|
206
|
+
"true_south_lunar_node": COLORS.southNode,
|
|
207
|
+
"nn": COLORS.northNode,
|
|
208
|
+
"sn": COLORS.southNode
|
|
209
|
+
};
|
|
210
|
+
return colorMap[name.toLowerCase()] || chalk.white;
|
|
211
|
+
}
|
|
212
|
+
function getZodiacColor(sign) {
|
|
213
|
+
const colorMap = {
|
|
214
|
+
"Ari": COLORS.mars,
|
|
215
|
+
"Tau": COLORS.venus,
|
|
216
|
+
"Gem": COLORS.mercury,
|
|
217
|
+
"Can": COLORS.moon,
|
|
218
|
+
"Leo": COLORS.sun,
|
|
219
|
+
"Vir": COLORS.mercury,
|
|
220
|
+
"Lib": COLORS.venus,
|
|
221
|
+
"Sco": COLORS.pluto,
|
|
222
|
+
"Sag": COLORS.jupiter,
|
|
223
|
+
"Cap": COLORS.saturn,
|
|
224
|
+
"Aqu": COLORS.uranus,
|
|
225
|
+
"Pis": COLORS.neptune
|
|
226
|
+
};
|
|
227
|
+
return colorMap[sign] || chalk.white;
|
|
228
|
+
}
|
|
229
|
+
function getAspectColor(aspect) {
|
|
230
|
+
const colorMap = {
|
|
231
|
+
"conjunction": COLORS.sun,
|
|
232
|
+
// Tiphareth
|
|
233
|
+
"opposition": COLORS.moon,
|
|
234
|
+
// Yesod
|
|
235
|
+
"trine": COLORS.jupiter,
|
|
236
|
+
// Chesed
|
|
237
|
+
"square": COLORS.mars,
|
|
238
|
+
// Geburah
|
|
239
|
+
"sextile": COLORS.venus,
|
|
240
|
+
// Netzach
|
|
241
|
+
"quintile": COLORS.mercury,
|
|
242
|
+
// Hod
|
|
243
|
+
"quincunx": COLORS.uranus
|
|
244
|
+
};
|
|
245
|
+
return colorMap[aspect] || chalk.white;
|
|
246
|
+
}
|
|
247
|
+
var ZODIAC_SYMBOLS = {
|
|
248
|
+
"Ari": "\u2648",
|
|
249
|
+
"Tau": "\u2649",
|
|
250
|
+
"Gem": "\u264A",
|
|
251
|
+
"Can": "\u264B",
|
|
252
|
+
"Leo": "\u264C",
|
|
253
|
+
"Vir": "\u264D",
|
|
254
|
+
"Lib": "\u264E",
|
|
255
|
+
"Sco": "\u264F",
|
|
256
|
+
"Sag": "\u2650",
|
|
257
|
+
"Cap": "\u2651",
|
|
258
|
+
"Aqu": "\u2652",
|
|
259
|
+
"Pis": "\u2653"
|
|
260
|
+
};
|
|
261
|
+
var PLANET_SYMBOLS = {
|
|
262
|
+
"sun": "\u2609",
|
|
263
|
+
"moon": "\u263D",
|
|
264
|
+
"mercury": "\u263F",
|
|
265
|
+
"venus": "\u2640",
|
|
266
|
+
"mars": "\u2642",
|
|
267
|
+
"jupiter": "\u2643",
|
|
268
|
+
"saturn": "\u2644",
|
|
269
|
+
"uranus": "\u2645",
|
|
270
|
+
"neptune": "\u2646",
|
|
271
|
+
"pluto": "\u2647",
|
|
272
|
+
"chiron": "\u26B7",
|
|
273
|
+
"north_node": "\u260A",
|
|
274
|
+
"south_node": "\u260B",
|
|
275
|
+
"true_north_lunar_node": "\u260A",
|
|
276
|
+
"true_south_lunar_node": "\u260B",
|
|
277
|
+
"mean_lilith": "\u26B8",
|
|
278
|
+
"medium_coeli": "MC",
|
|
279
|
+
"imum_coeli": "IC",
|
|
280
|
+
"ascendant": "ASC",
|
|
281
|
+
"descendant": "DSC",
|
|
282
|
+
// Short names from transit aspects
|
|
283
|
+
"nn": "\u260A",
|
|
284
|
+
"sn": "\u260B",
|
|
285
|
+
"lilith": "\u26B8",
|
|
286
|
+
"mc": "MC",
|
|
287
|
+
"ic": "IC",
|
|
288
|
+
"asc": "ASC",
|
|
289
|
+
"dsc": "DSC"
|
|
290
|
+
};
|
|
291
|
+
var ASPECT_SYMBOLS = {
|
|
292
|
+
"conjunction": "\u260C",
|
|
293
|
+
"opposition": "\u260D",
|
|
294
|
+
"trine": "\u25B3",
|
|
295
|
+
"square": "\u25A1",
|
|
296
|
+
"sextile": "\u26B9",
|
|
297
|
+
"quintile": "\u235F",
|
|
298
|
+
"quincunx": "\u26BB",
|
|
299
|
+
"semi-sextile": "\u26BA",
|
|
300
|
+
"semi-square": "\u2220",
|
|
301
|
+
"sesquiquadrate": "\u26BC"
|
|
302
|
+
};
|
|
303
|
+
function getZodiacSymbol(sign) {
|
|
304
|
+
const key = sign.slice(0, 3);
|
|
305
|
+
return ZODIAC_SYMBOLS[key] || sign;
|
|
306
|
+
}
|
|
307
|
+
function getPlanetSymbol(planet) {
|
|
308
|
+
return PLANET_SYMBOLS[planet.toLowerCase()] || planet;
|
|
309
|
+
}
|
|
310
|
+
function getAspectSymbol(aspect) {
|
|
311
|
+
return ASPECT_SYMBOLS[aspect.toLowerCase()] || aspect;
|
|
312
|
+
}
|
|
313
|
+
function formatDegrees(degrees) {
|
|
314
|
+
const d = Math.floor(degrees);
|
|
315
|
+
const m = Math.floor((degrees - d) * 60);
|
|
316
|
+
return `${d}\xB0${m.toString().padStart(2, "0")}'`;
|
|
317
|
+
}
|
|
318
|
+
function formatChart(result) {
|
|
319
|
+
const lines = [];
|
|
320
|
+
lines.push(chalk.bold.white(`
|
|
321
|
+
\u{1315D} Natal Chart: ${result.name}`));
|
|
322
|
+
const dateStr = `${result.datetime.year}-${String(result.datetime.month).padStart(2, "0")}-${String(result.datetime.day).padStart(2, "0")} ${String(result.datetime.hour).padStart(2, "0")}:${String(result.datetime.minute).padStart(2, "0")}`;
|
|
323
|
+
lines.push(chalk.dim(` ${dateStr}`));
|
|
324
|
+
if (result.location.city) {
|
|
325
|
+
lines.push(chalk.dim(` ${result.location.city}`));
|
|
326
|
+
} else {
|
|
327
|
+
lines.push(chalk.dim(` Lat: ${result.location.lat}, Lng: ${result.location.lng}`));
|
|
328
|
+
}
|
|
329
|
+
if (result.lunar_phase) {
|
|
330
|
+
lines.push(chalk.dim(` Born during: ${result.lunar_phase.emoji} ${result.lunar_phase.name}`));
|
|
331
|
+
}
|
|
332
|
+
lines.push("");
|
|
333
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 ANGLES \u2500\u2500"));
|
|
334
|
+
if (result.ascendant.sign) {
|
|
335
|
+
const zColor = getZodiacColor(result.ascendant.sign);
|
|
336
|
+
lines.push(` ${COLORS.mars("ASC")} ${zColor(getZodiacSymbol(result.ascendant.sign) + " " + result.ascendant.sign)} ${chalk.white(formatDegrees(result.ascendant.position || 0))}`);
|
|
337
|
+
}
|
|
338
|
+
if (result.midheaven.sign) {
|
|
339
|
+
const zColor = getZodiacColor(result.midheaven.sign);
|
|
340
|
+
lines.push(` ${COLORS.sun("MC")} ${zColor(getZodiacSymbol(result.midheaven.sign) + " " + result.midheaven.sign)} ${chalk.white(formatDegrees(result.midheaven.position || 0))}`);
|
|
341
|
+
}
|
|
342
|
+
lines.push("");
|
|
343
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 PLANETS \u2500\u2500"));
|
|
344
|
+
const planetOrder = ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"];
|
|
345
|
+
for (const name of planetOrder) {
|
|
346
|
+
const planet = result.planets[name];
|
|
347
|
+
if (planet) {
|
|
348
|
+
const pColor = getPlanetColor(name);
|
|
349
|
+
const zColor = getZodiacColor(planet.sign);
|
|
350
|
+
const symbol = getPlanetSymbol(name);
|
|
351
|
+
const zodiac = getZodiacSymbol(planet.sign);
|
|
352
|
+
const deg = formatDegrees(planet.position);
|
|
353
|
+
const rx = planet.retrograde ? COLORS.mars(" \u211E") : "";
|
|
354
|
+
const house = planet.house ? chalk.dim(` (${planet.house})`) : "";
|
|
355
|
+
lines.push(` ${pColor(symbol)} ${name.padEnd(10)} ${zColor(zodiac + " " + planet.sign)} ${chalk.white(deg)}${rx}${house}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
lines.push("");
|
|
359
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 POINTS \u2500\u2500"));
|
|
360
|
+
const pointOrder = ["chiron", "mean_lilith", "true_north_lunar_node", "true_south_lunar_node"];
|
|
361
|
+
const pointNames = {
|
|
362
|
+
"chiron": "Chiron",
|
|
363
|
+
"mean_lilith": "Lilith",
|
|
364
|
+
"true_north_lunar_node": "North Node",
|
|
365
|
+
"true_south_lunar_node": "South Node"
|
|
366
|
+
};
|
|
367
|
+
for (const name of pointOrder) {
|
|
368
|
+
const planet = result.planets[name];
|
|
369
|
+
if (planet) {
|
|
370
|
+
const pColor = getPlanetColor(name);
|
|
371
|
+
const zColor = getZodiacColor(planet.sign);
|
|
372
|
+
const symbol = getPlanetSymbol(name);
|
|
373
|
+
const displayName = pointNames[name] || name;
|
|
374
|
+
const zodiac = getZodiacSymbol(planet.sign);
|
|
375
|
+
const deg = formatDegrees(planet.position);
|
|
376
|
+
const house = planet.house ? chalk.dim(` (${planet.house})`) : "";
|
|
377
|
+
lines.push(` ${pColor(symbol)} ${displayName.padEnd(10)} ${zColor(zodiac + " " + planet.sign)} ${chalk.white(deg)}${house}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
lines.push("");
|
|
381
|
+
if (result.houses && Object.keys(result.houses).length > 0) {
|
|
382
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 HOUSES \u2500\u2500"));
|
|
383
|
+
for (let i = 1; i <= 12; i++) {
|
|
384
|
+
const house = result.houses[String(i)];
|
|
385
|
+
if (house && house.sign) {
|
|
386
|
+
const zodiac = getZodiacSymbol(house.sign);
|
|
387
|
+
const deg = formatDegrees(house.position || 0);
|
|
388
|
+
const label = i === 1 ? "(ASC)" : i === 4 ? "(IC)" : i === 7 ? "(DSC)" : i === 10 ? "(MC)" : "";
|
|
389
|
+
lines.push(` ${String(i).padStart(2)} ${chalk.cyan(zodiac)} ${house.sign} ${chalk.dim(deg)} ${chalk.yellow(label)}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
lines.push("");
|
|
393
|
+
}
|
|
394
|
+
if (result.elements && result.modes) {
|
|
395
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 BALANCE \u2500\u2500"));
|
|
396
|
+
const elem = result.elements;
|
|
397
|
+
const mode = result.modes;
|
|
398
|
+
lines.push(` ${COLORS.mars("\u{1F702} Fire:")} ${elem.Fire} ${COLORS.venus("\u{1F703} Earth:")} ${elem.Earth} ${COLORS.mercury("\u{1F701} Air:")} ${elem.Air} ${COLORS.moon("\u{1F704} Water:")} ${elem.Water}`);
|
|
399
|
+
lines.push(` ${COLORS.mars("Cardinal:")} ${mode.Cardinal} ${COLORS.sun("Fixed:")} ${mode.Fixed} ${COLORS.mercury("Mutable:")} ${mode.Mutable}`);
|
|
400
|
+
lines.push("");
|
|
401
|
+
}
|
|
402
|
+
if (result.aspects && result.aspects.length > 0) {
|
|
403
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 ASPECTS \u2500\u2500"));
|
|
404
|
+
const aspects = result.aspects.slice(0, 15);
|
|
405
|
+
for (const asp of aspects) {
|
|
406
|
+
const p1Name = asp.planet1.toLowerCase().replace(/ /g, "_");
|
|
407
|
+
const p2Name = asp.planet2.toLowerCase().replace(/ /g, "_");
|
|
408
|
+
const p1Color = getPlanetColor(p1Name);
|
|
409
|
+
const p2Color = getPlanetColor(p2Name);
|
|
410
|
+
const p1 = getPlanetSymbol(p1Name);
|
|
411
|
+
const p2 = getPlanetSymbol(p2Name);
|
|
412
|
+
const aspectSym = getAspectSymbol(asp.aspect);
|
|
413
|
+
const aspectName = asp.aspect.charAt(0).toUpperCase() + asp.aspect.slice(1);
|
|
414
|
+
const aColor = getAspectColor(asp.aspect);
|
|
415
|
+
lines.push(` ${p1Color(p1)} ${asp.planet1.padEnd(10)} ${aColor(aspectSym + " " + aspectName.padEnd(11))} ${p2Color(p2)} ${asp.planet2.padEnd(10)} ${chalk.dim(`${asp.orb}\xB0`)}`);
|
|
416
|
+
}
|
|
417
|
+
lines.push("");
|
|
418
|
+
}
|
|
419
|
+
return lines.join("\n");
|
|
420
|
+
}
|
|
421
|
+
function formatTransits(result) {
|
|
422
|
+
const lines = [];
|
|
423
|
+
lines.push(chalk.bold.white(`
|
|
424
|
+
\u{1315D} Transits`));
|
|
425
|
+
if (result.natal.name) {
|
|
426
|
+
lines.push(chalk.dim(` For: ${result.natal.name}`));
|
|
427
|
+
}
|
|
428
|
+
if (result.natal.city) {
|
|
429
|
+
lines.push(chalk.dim(` Natal: ${result.natal.datetime} \xB7 ${result.natal.city}`));
|
|
430
|
+
} else {
|
|
431
|
+
lines.push(chalk.dim(` Natal: ${result.natal.datetime}`));
|
|
432
|
+
}
|
|
433
|
+
lines.push(chalk.dim(` Transit: ${result.transit.datetime}`));
|
|
434
|
+
if (result.transit.lunar_phase) {
|
|
435
|
+
lines.push(chalk.dim(` Moon: ${result.transit.lunar_phase.emoji} ${result.transit.lunar_phase.name}`));
|
|
436
|
+
}
|
|
437
|
+
lines.push("");
|
|
438
|
+
if (result.transit.planets) {
|
|
439
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 CURRENT SKY \u2500\u2500"));
|
|
440
|
+
const planets = result.transit.planets;
|
|
441
|
+
for (const name of ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"]) {
|
|
442
|
+
const planet = planets[name];
|
|
443
|
+
if (planet) {
|
|
444
|
+
const pColor = getPlanetColor(name);
|
|
445
|
+
const zColor = getZodiacColor(planet.sign);
|
|
446
|
+
const symbol = getPlanetSymbol(name);
|
|
447
|
+
const zodiac = getZodiacSymbol(planet.sign);
|
|
448
|
+
const deg = formatDegrees(planet.position);
|
|
449
|
+
const rx = planet.retrograde ? COLORS.mars("\u211E") : " ";
|
|
450
|
+
const cH = planet.house ? planet.house.replace(/ house/i, "").replace(/first/i, "1").replace(/second/i, "2").replace(/third/i, "3").replace(/fourth/i, "4").replace(/fifth/i, "5").replace(/sixth/i, "6").replace(/seventh/i, "7").replace(/eighth/i, "8").replace(/ninth/i, "9").replace(/tenth/i, "10").replace(/eleventh/i, "11").replace(/twelfth/i, "12") : "?";
|
|
451
|
+
lines.push(` ${pColor(symbol)} ${zColor(zodiac + " " + planet.sign)} ${chalk.white(deg)} ${rx} ${chalk.dim(`${cH}H`)}`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
lines.push("");
|
|
455
|
+
}
|
|
456
|
+
const transitHouses = result.transit.houses;
|
|
457
|
+
const natalHouses = result.natal_houses;
|
|
458
|
+
if (transitHouses && natalHouses && Object.keys(transitHouses).length > 0) {
|
|
459
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 HOUSES \u2500\u2500"));
|
|
460
|
+
lines.push(chalk.dim(" TRANSIT NATAL"));
|
|
461
|
+
for (let i = 1; i <= 12; i++) {
|
|
462
|
+
const tH = transitHouses[String(i)];
|
|
463
|
+
const nH = natalHouses[String(i)];
|
|
464
|
+
if (tH && nH) {
|
|
465
|
+
const label = i === 1 ? "ASC" : i === 4 ? "IC" : i === 7 ? "DSC" : i === 10 ? "MC" : `${i}`.padStart(2) + "H";
|
|
466
|
+
const tZColor = getZodiacColor(tH.sign);
|
|
467
|
+
const nZColor = getZodiacColor(nH.sign);
|
|
468
|
+
const tZodiac = getZodiacSymbol(tH.sign);
|
|
469
|
+
const nZodiac = getZodiacSymbol(nH.sign);
|
|
470
|
+
const tDeg = formatDegrees(tH.position);
|
|
471
|
+
const nDeg = formatDegrees(nH.position);
|
|
472
|
+
lines.push(` ${chalk.white(label.padStart(3))} ${tZColor(tZodiac + " " + tH.sign)} ${chalk.dim(tDeg)} ${nZColor(nZodiac + " " + nH.sign)} ${chalk.dim(nDeg)}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
lines.push("");
|
|
476
|
+
}
|
|
477
|
+
lines.push(chalk.bold.cyan("\u2500\u2500 TRANSITS TO NATAL \u2500\u2500"));
|
|
478
|
+
if (result.aspects.length === 0) {
|
|
479
|
+
lines.push(chalk.dim(" No aspects within orb"));
|
|
480
|
+
} else {
|
|
481
|
+
const shortName = (name) => {
|
|
482
|
+
const map = {
|
|
483
|
+
"sun": "SUN",
|
|
484
|
+
"moon": "MOO",
|
|
485
|
+
"mercury": "MER",
|
|
486
|
+
"venus": "VEN",
|
|
487
|
+
"mars": "MAR",
|
|
488
|
+
"jupiter": "JUP",
|
|
489
|
+
"saturn": "SAT",
|
|
490
|
+
"uranus": "URA",
|
|
491
|
+
"neptune": "NEP",
|
|
492
|
+
"pluto": "PLU",
|
|
493
|
+
"chiron": "CHI",
|
|
494
|
+
"nn": "NN",
|
|
495
|
+
"sn": "SN",
|
|
496
|
+
"lilith": "LIL",
|
|
497
|
+
"mc": "MC",
|
|
498
|
+
"ic": "IC",
|
|
499
|
+
"asc": "ASC",
|
|
500
|
+
"dsc": "DSC"
|
|
501
|
+
};
|
|
502
|
+
return map[name.toLowerCase()] || name.slice(0, 3).toUpperCase();
|
|
503
|
+
};
|
|
504
|
+
for (const aspect of result.aspects) {
|
|
505
|
+
const tPlanet = aspect.transit_planet.toLowerCase().replace(/ /g, "_");
|
|
506
|
+
const nPlanet = aspect.natal_planet.toLowerCase().replace(/ /g, "_");
|
|
507
|
+
const tColor = getPlanetColor(tPlanet);
|
|
508
|
+
const nColor = getPlanetColor(nPlanet);
|
|
509
|
+
const tSym = getPlanetSymbol(tPlanet);
|
|
510
|
+
const nSym = getPlanetSymbol(nPlanet);
|
|
511
|
+
const tName = shortName(aspect.transit_planet);
|
|
512
|
+
const nName = shortName(aspect.natal_planet);
|
|
513
|
+
const aSym = getAspectSymbol(aspect.aspect);
|
|
514
|
+
const aColor = getAspectColor(aspect.aspect);
|
|
515
|
+
const aspectShort = aspect.aspect === "conjunction" ? "CNJ" : aspect.aspect === "opposition" ? "OPP" : aspect.aspect === "trine" ? "TRI" : aspect.aspect === "square" ? "SQR" : aspect.aspect === "sextile" ? "SXT" : aspect.aspect === "quintile" ? "QNT" : aspect.aspect === "quincunx" ? "QCX" : String(aspect.aspect).slice(0, 3).toUpperCase();
|
|
516
|
+
const tH = aspect.transit_house;
|
|
517
|
+
const nH = aspect.natal_house;
|
|
518
|
+
const houses = `${tH || "?"}H\u2192${nH || "?"}H`;
|
|
519
|
+
const orb = aspect.orb.toFixed(2).padStart(5);
|
|
520
|
+
lines.push(` ${tColor(tSym)} ${tName.padEnd(3)} ${aColor(aSym + " " + aspectShort)} ${nColor(nSym)} ${nName.padEnd(3)} ${chalk.dim(orb + "\xB0")} ${chalk.dim(houses)}`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
lines.push("");
|
|
524
|
+
return lines.join("\n");
|
|
525
|
+
}
|
|
526
|
+
function formatMoon(result) {
|
|
527
|
+
const lines = [];
|
|
528
|
+
const moonEmoji = result.phase.illumination > 50 ? "\u{1F315}" : "\u{1F311}";
|
|
529
|
+
const zColor = getZodiacColor(result.moon.sign);
|
|
530
|
+
lines.push(chalk.bold.white(`
|
|
531
|
+
${moonEmoji} Moon Phase`));
|
|
532
|
+
lines.push(chalk.dim(` ${result.datetime}`));
|
|
533
|
+
lines.push("");
|
|
534
|
+
lines.push(` ${COLORS.moon("\u263D")} ${chalk.white("Moon in")} ${zColor(result.moon.sign)} ${chalk.white(formatDegrees(result.moon.position))}`);
|
|
535
|
+
lines.push(` ${chalk.white("Phase:")} ${COLORS.moon(result.phase.name)}`);
|
|
536
|
+
lines.push(` ${chalk.white("Illumination:")} ${COLORS.moon(result.phase.illumination.toFixed(1) + "%")}`);
|
|
537
|
+
lines.push("");
|
|
538
|
+
return lines.join("\n");
|
|
539
|
+
}
|
|
540
|
+
function formatEphemeris(result) {
|
|
541
|
+
const lines = [];
|
|
542
|
+
const pColor = getPlanetColor(result.body);
|
|
543
|
+
const zColor = getZodiacColor(result.sign);
|
|
544
|
+
const symbol = getPlanetSymbol(result.body);
|
|
545
|
+
const rx = result.retrograde ? COLORS.mars(" \u211E") : "";
|
|
546
|
+
lines.push(chalk.bold.white(`
|
|
547
|
+
\u{1315D} Ephemeris: ${result.body}`));
|
|
548
|
+
lines.push(chalk.dim(` ${result.datetime}`));
|
|
549
|
+
lines.push("");
|
|
550
|
+
lines.push(` ${pColor(symbol)} ${chalk.white(result.body)} in ${zColor(result.sign)} ${chalk.white(formatDegrees(result.position))}${rx}`);
|
|
551
|
+
lines.push(` ${chalk.dim(`Absolute: ${result.abs_position.toFixed(4)}\xB0`)}`);
|
|
552
|
+
lines.push("");
|
|
553
|
+
return lines.join("\n");
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/types.ts
|
|
557
|
+
function isError(result) {
|
|
558
|
+
return "error" in result;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export {
|
|
562
|
+
chart,
|
|
563
|
+
transit,
|
|
564
|
+
moon,
|
|
565
|
+
ephemeris,
|
|
566
|
+
version,
|
|
567
|
+
getZodiacSymbol,
|
|
568
|
+
getPlanetSymbol,
|
|
569
|
+
getAspectSymbol,
|
|
570
|
+
formatDegrees,
|
|
571
|
+
formatChart,
|
|
572
|
+
formatTransits,
|
|
573
|
+
formatMoon,
|
|
574
|
+
formatEphemeris,
|
|
575
|
+
isError
|
|
576
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thoth CLI Types
|
|
3
|
+
* 𓅝
|
|
4
|
+
*/
|
|
5
|
+
interface Planet {
|
|
6
|
+
sign: string;
|
|
7
|
+
position: number;
|
|
8
|
+
abs_position: number;
|
|
9
|
+
house?: number | null;
|
|
10
|
+
retrograde: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface House {
|
|
13
|
+
sign: string | null;
|
|
14
|
+
position: number | null;
|
|
15
|
+
}
|
|
16
|
+
interface ChartResult {
|
|
17
|
+
name: string;
|
|
18
|
+
datetime: {
|
|
19
|
+
year: number;
|
|
20
|
+
month: number;
|
|
21
|
+
day: number;
|
|
22
|
+
hour: number;
|
|
23
|
+
minute: number;
|
|
24
|
+
};
|
|
25
|
+
location: {
|
|
26
|
+
lat: number;
|
|
27
|
+
lng: number;
|
|
28
|
+
};
|
|
29
|
+
planets: Record<string, Planet>;
|
|
30
|
+
houses: Record<string, House>;
|
|
31
|
+
ascendant: {
|
|
32
|
+
sign: string | null;
|
|
33
|
+
position: number | null;
|
|
34
|
+
};
|
|
35
|
+
midheaven: {
|
|
36
|
+
sign: string | null;
|
|
37
|
+
position: number | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
interface Aspect {
|
|
41
|
+
transit_planet: string;
|
|
42
|
+
natal_planet: string;
|
|
43
|
+
aspect: 'conjunction' | 'opposition' | 'trine' | 'square' | 'sextile';
|
|
44
|
+
orb: number;
|
|
45
|
+
transit_position: number;
|
|
46
|
+
natal_position: number;
|
|
47
|
+
applying: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface TransitResult {
|
|
50
|
+
natal: {
|
|
51
|
+
datetime: string;
|
|
52
|
+
};
|
|
53
|
+
transit: {
|
|
54
|
+
datetime: string;
|
|
55
|
+
};
|
|
56
|
+
aspects: Aspect[];
|
|
57
|
+
}
|
|
58
|
+
interface MoonResult {
|
|
59
|
+
datetime: string;
|
|
60
|
+
moon: {
|
|
61
|
+
sign: string;
|
|
62
|
+
position: number;
|
|
63
|
+
abs_position: number;
|
|
64
|
+
};
|
|
65
|
+
phase: {
|
|
66
|
+
name: string;
|
|
67
|
+
angle: number;
|
|
68
|
+
illumination: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
interface EphemerisResult {
|
|
72
|
+
body: string;
|
|
73
|
+
datetime: string;
|
|
74
|
+
sign: string;
|
|
75
|
+
position: number;
|
|
76
|
+
abs_position: number;
|
|
77
|
+
retrograde: boolean;
|
|
78
|
+
}
|
|
79
|
+
interface ChartOptions {
|
|
80
|
+
year: number;
|
|
81
|
+
month: number;
|
|
82
|
+
day: number;
|
|
83
|
+
hour?: number;
|
|
84
|
+
minute?: number;
|
|
85
|
+
lat?: number;
|
|
86
|
+
lng?: number;
|
|
87
|
+
city?: string;
|
|
88
|
+
nation?: string;
|
|
89
|
+
name?: string;
|
|
90
|
+
}
|
|
91
|
+
interface TransitOptions {
|
|
92
|
+
natalYear: number;
|
|
93
|
+
natalMonth: number;
|
|
94
|
+
natalDay: number;
|
|
95
|
+
natalHour?: number;
|
|
96
|
+
natalMinute?: number;
|
|
97
|
+
natalLat?: number;
|
|
98
|
+
natalLng?: number;
|
|
99
|
+
natalCity?: string;
|
|
100
|
+
nation?: string;
|
|
101
|
+
transitYear?: number;
|
|
102
|
+
transitMonth?: number;
|
|
103
|
+
transitDay?: number;
|
|
104
|
+
orb?: number;
|
|
105
|
+
}
|
|
106
|
+
interface MoonOptions {
|
|
107
|
+
year?: number;
|
|
108
|
+
month?: number;
|
|
109
|
+
day?: number;
|
|
110
|
+
lat?: number;
|
|
111
|
+
lng?: number;
|
|
112
|
+
}
|
|
113
|
+
interface EphemerisOptions {
|
|
114
|
+
body: string;
|
|
115
|
+
year?: number;
|
|
116
|
+
month?: number;
|
|
117
|
+
day?: number;
|
|
118
|
+
}
|
|
119
|
+
interface ThothError {
|
|
120
|
+
error: string;
|
|
121
|
+
}
|
|
122
|
+
type ThothResult<T> = T | ThothError;
|
|
123
|
+
declare function isError<T extends object>(result: ThothResult<T>): result is ThothError;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Core wrapper for thoth-core binary
|
|
127
|
+
* 𓅝
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Calculate a natal chart
|
|
132
|
+
*/
|
|
133
|
+
declare function chart(options: ChartOptions): Promise<ThothResult<ChartResult>>;
|
|
134
|
+
/**
|
|
135
|
+
* Calculate transits to a natal chart
|
|
136
|
+
*/
|
|
137
|
+
declare function transit(options: TransitOptions): Promise<ThothResult<TransitResult>>;
|
|
138
|
+
/**
|
|
139
|
+
* Get moon phase and position
|
|
140
|
+
*/
|
|
141
|
+
declare function moon(options?: MoonOptions): Promise<ThothResult<MoonResult>>;
|
|
142
|
+
/**
|
|
143
|
+
* Get ephemeris position for a celestial body
|
|
144
|
+
*/
|
|
145
|
+
declare function ephemeris(options: EphemerisOptions): Promise<ThothResult<EphemerisResult>>;
|
|
146
|
+
/**
|
|
147
|
+
* Get version
|
|
148
|
+
*/
|
|
149
|
+
declare function version(): Promise<ThothResult<{
|
|
150
|
+
version: string;
|
|
151
|
+
}>>;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Output formatting utilities
|
|
155
|
+
* 𓅝
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get zodiac symbol
|
|
160
|
+
*/
|
|
161
|
+
declare function getZodiacSymbol(sign: string): string;
|
|
162
|
+
/**
|
|
163
|
+
* Get planet symbol
|
|
164
|
+
*/
|
|
165
|
+
declare function getPlanetSymbol(planet: string): string;
|
|
166
|
+
/**
|
|
167
|
+
* Get aspect symbol
|
|
168
|
+
*/
|
|
169
|
+
declare function getAspectSymbol(aspect: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* Format degrees to degrees, minutes, seconds
|
|
172
|
+
*/
|
|
173
|
+
declare function formatDegrees(degrees: number): string;
|
|
174
|
+
/**
|
|
175
|
+
* Format a chart result
|
|
176
|
+
*/
|
|
177
|
+
declare function formatChart(result: ChartResult): string;
|
|
178
|
+
/**
|
|
179
|
+
* Format transits result
|
|
180
|
+
*/
|
|
181
|
+
declare function formatTransits(result: TransitResult): string;
|
|
182
|
+
/**
|
|
183
|
+
* Format moon result
|
|
184
|
+
*/
|
|
185
|
+
declare function formatMoon(result: MoonResult): string;
|
|
186
|
+
/**
|
|
187
|
+
* Format ephemeris result
|
|
188
|
+
*/
|
|
189
|
+
declare function formatEphemeris(result: EphemerisResult): string;
|
|
190
|
+
|
|
191
|
+
export { type Aspect, type ChartOptions, type ChartResult, type EphemerisOptions, type EphemerisResult, type House, type MoonOptions, type MoonResult, type Planet, type ThothError, type ThothResult, type TransitOptions, type TransitResult, chart, ephemeris, formatChart, formatDegrees, formatEphemeris, formatMoon, formatTransits, getAspectSymbol, getPlanetSymbol, getZodiacSymbol, isError, moon, transit, version };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chart,
|
|
3
|
+
ephemeris,
|
|
4
|
+
formatChart,
|
|
5
|
+
formatDegrees,
|
|
6
|
+
formatEphemeris,
|
|
7
|
+
formatMoon,
|
|
8
|
+
formatTransits,
|
|
9
|
+
getAspectSymbol,
|
|
10
|
+
getPlanetSymbol,
|
|
11
|
+
getZodiacSymbol,
|
|
12
|
+
isError,
|
|
13
|
+
moon,
|
|
14
|
+
transit,
|
|
15
|
+
version
|
|
16
|
+
} from "./chunk-NYXKYHNK.js";
|
|
17
|
+
export {
|
|
18
|
+
chart,
|
|
19
|
+
ephemeris,
|
|
20
|
+
formatChart,
|
|
21
|
+
formatDegrees,
|
|
22
|
+
formatEphemeris,
|
|
23
|
+
formatMoon,
|
|
24
|
+
formatTransits,
|
|
25
|
+
getAspectSymbol,
|
|
26
|
+
getPlanetSymbol,
|
|
27
|
+
getZodiacSymbol,
|
|
28
|
+
isError,
|
|
29
|
+
moon,
|
|
30
|
+
transit,
|
|
31
|
+
version
|
|
32
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "thoth-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "𓅝 Astrological calculations from the command line. Swiss Ephemeris precision. Built for humans and agents.",
|
|
5
|
+
"author": "AKLO <aklo@aklolabs.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"thoth": "./dist/bin.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"bin"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup src/index.ts src/bin.ts --format esm --dts --clean",
|
|
19
|
+
"dev": "tsup src/index.ts src/bin.ts --format esm --dts --watch",
|
|
20
|
+
"postinstall": "node scripts/postinstall.js",
|
|
21
|
+
"test": "vitest"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"chalk": "^5.3.0",
|
|
25
|
+
"commander": "^12.0.0",
|
|
26
|
+
"ora": "^8.0.0",
|
|
27
|
+
"execa": "^8.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.0.0",
|
|
31
|
+
"tsup": "^8.0.0",
|
|
32
|
+
"typescript": "^5.0.0",
|
|
33
|
+
"vitest": "^1.0.0"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"astrology",
|
|
40
|
+
"cli",
|
|
41
|
+
"ephemeris",
|
|
42
|
+
"horoscope",
|
|
43
|
+
"natal-chart",
|
|
44
|
+
"thoth"
|
|
45
|
+
],
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/aklo/thoth-cli.git"
|
|
49
|
+
}
|
|
50
|
+
}
|