thoth-cli 0.2.21 → 0.2.23

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.
Binary file
package/dist/bin.js CHANGED
@@ -19,6 +19,10 @@ import {
19
19
  formatSolarArc,
20
20
  formatSolarReturn,
21
21
  formatSynastry,
22
+ formatTarotCard,
23
+ formatTarotDeck,
24
+ formatTarotDraw,
25
+ formatTarotSpreads,
22
26
  formatTransitScan,
23
27
  formatTransits,
24
28
  horary,
@@ -31,10 +35,14 @@ import {
31
35
  solarArc,
32
36
  solarReturn,
33
37
  synastry,
38
+ tarotCard,
39
+ tarotDeck,
40
+ tarotDraw,
41
+ tarotSpreads,
34
42
  transit,
35
43
  transitScan,
36
44
  version
37
- } from "./chunk-QND56LGZ.js";
45
+ } from "./chunk-X7IGMJUH.js";
38
46
 
39
47
  // src/bin.ts
40
48
  import { Command } from "commander";
@@ -796,7 +804,62 @@ program.command("ephemeris-multi").description("Get ephemeris for multiple bodie
796
804
  console.log(formatEphemerisMulti(result));
797
805
  }
798
806
  });
807
+ program.command("tarot").alias("draw").description("Draw tarot cards (cryptographic randomness)").option("-s, --spread <spread>", "Spread: single, 3-card, celtic, horseshoe, relationship, decision", "single").option("-q, --question <question>", "Question for the reading").option("-n, --count <count>", "Number of cards (for custom spread)", parseInt).option("--no-reversals", "Disable reversed cards").option("--json", "Output raw JSON").action(async (options) => {
808
+ const spinner = ora("Shuffling the deck...").start();
809
+ const result = await tarotDraw({
810
+ spread: options.spread,
811
+ question: options.question,
812
+ count: options.count,
813
+ reversals: options.reversals
814
+ });
815
+ spinner.stop();
816
+ if (isError(result)) {
817
+ console.error(chalk.red("Error: " + result.error));
818
+ process.exit(1);
819
+ }
820
+ if (options.json) {
821
+ console.log(JSON.stringify(result, null, 2));
822
+ } else {
823
+ console.log(formatTarotDraw(result));
824
+ }
825
+ });
826
+ program.command("tarot-card <card>").alias("card").description("Look up a tarot card by name or number").option("--json", "Output raw JSON").action(async (card, options) => {
827
+ const result = await tarotCard(card);
828
+ if (isError(result)) {
829
+ console.error(chalk.red("Error: " + result.error));
830
+ process.exit(1);
831
+ }
832
+ if (options.json) {
833
+ console.log(JSON.stringify(result, null, 2));
834
+ } else {
835
+ console.log(formatTarotCard(result));
836
+ }
837
+ });
838
+ program.command("tarot-deck").alias("deck").description("List tarot cards").option("-f, --filter <filter>", "Filter: major, minor, wands, cups, swords, pentacles").option("--json", "Output raw JSON").action(async (options) => {
839
+ const result = await tarotDeck(options.filter);
840
+ if (isError(result)) {
841
+ console.error(chalk.red("Error: " + result.error));
842
+ process.exit(1);
843
+ }
844
+ if (options.json) {
845
+ console.log(JSON.stringify(result, null, 2));
846
+ } else {
847
+ console.log(formatTarotDeck(result));
848
+ }
849
+ });
850
+ program.command("tarot-spreads").alias("spreads").description("List available tarot spreads").option("--json", "Output raw JSON").action(async (options) => {
851
+ const result = await tarotSpreads();
852
+ if (isError(result)) {
853
+ console.error(chalk.red("Error: " + result.error));
854
+ process.exit(1);
855
+ }
856
+ if (options.json) {
857
+ console.log(JSON.stringify(result, null, 2));
858
+ } else {
859
+ console.log(formatTarotSpreads(result));
860
+ }
861
+ });
799
862
  console.log(chalk.dim(""));
800
- console.log(chalk.yellow(" \u{1315D}") + chalk.dim(" thoth-cli v0.2.21"));
863
+ console.log(chalk.yellow(" \u{1315D}") + chalk.dim(" thoth-cli v0.2.23"));
801
864
  console.log(chalk.dim(""));
802
865
  program.parse();
@@ -514,6 +514,25 @@ async function ephemerisMulti(options) {
514
514
  if (options.lng !== void 0) args.push("--lng", String(options.lng));
515
515
  return execute("ephemeris-multi", args);
516
516
  }
517
+ async function tarotDraw(options) {
518
+ const args = [];
519
+ if (options.count) args.push("--count", String(options.count));
520
+ if (options.spread) args.push("--spread", options.spread);
521
+ if (options.question) args.push("--question", options.question);
522
+ if (options.reversals === false) args.push("--no-reversals");
523
+ return execute("tarot-draw", args);
524
+ }
525
+ async function tarotCard(identifier) {
526
+ return execute("tarot-card", [identifier]);
527
+ }
528
+ async function tarotDeck(filter) {
529
+ const args = [];
530
+ if (filter) args.push("--filter", filter);
531
+ return execute("tarot-deck", args);
532
+ }
533
+ async function tarotSpreads() {
534
+ return execute("tarot-spreads", []);
535
+ }
517
536
 
518
537
  // src/lib/format.ts
519
538
  import chalk from "chalk";
@@ -1434,6 +1453,159 @@ function formatEphemerisMulti(result) {
1434
1453
  lines.push("");
1435
1454
  return lines.join("\n");
1436
1455
  }
1456
+ var TAROT_COLORS = {
1457
+ major: chalk.hex("#FFD700"),
1458
+ // Gold for Major Arcana
1459
+ wands: chalk.hex("#FF4500"),
1460
+ // Fire - Orange Red
1461
+ cups: chalk.hex("#4169E1"),
1462
+ // Water - Royal Blue
1463
+ swords: chalk.hex("#E0E0E0"),
1464
+ // Air - Silver
1465
+ pentacles: chalk.hex("#228B22")
1466
+ // Earth - Forest Green
1467
+ };
1468
+ function getTarotColor(card) {
1469
+ if (card.arcana === "major") return TAROT_COLORS.major;
1470
+ return TAROT_COLORS[card.suit] || chalk.white;
1471
+ }
1472
+ function getSuitSymbol(suit) {
1473
+ const symbols = {
1474
+ wands: "\u{1F702}",
1475
+ // Fire alchemical symbol
1476
+ cups: "\u{1F704}",
1477
+ // Water alchemical symbol
1478
+ swords: "\u{1F701}",
1479
+ // Air alchemical symbol
1480
+ pentacles: "\u{1F703}"
1481
+ // Earth alchemical symbol
1482
+ };
1483
+ return symbols[suit] || "";
1484
+ }
1485
+ function formatTarotDraw(result) {
1486
+ const lines = [];
1487
+ lines.push("");
1488
+ lines.push(chalk.bold.hex("#9932CC")("\u{1F3B4} TAROT READING"));
1489
+ lines.push(` ${chalk.dim("Spread:")} ${result.spread_name}`);
1490
+ if (result.question) {
1491
+ lines.push(` ${chalk.dim("Question:")} "${result.question}"`);
1492
+ }
1493
+ lines.push(` ${chalk.dim("Entropy:")} ${result.entropy_source}`);
1494
+ lines.push(` ${chalk.dim("Time:")} ${result.timestamp}`);
1495
+ lines.push("");
1496
+ lines.push(chalk.bold.cyan("\u2500\u2500 THE CARDS \u2500\u2500"));
1497
+ lines.push("");
1498
+ for (const card of result.cards) {
1499
+ const color = getTarotColor(card);
1500
+ const reversed = card.reversed ? chalk.red(" \u211E REVERSED") : "";
1501
+ const suitSymbol = card.suit ? ` ${getSuitSymbol(card.suit)}` : "";
1502
+ lines.push(` ${chalk.bold.white(`[${card.position}] ${card.position_name}`)}`);
1503
+ lines.push(` ${color(card.name)}${suitSymbol}${reversed}`);
1504
+ if (card.arcana === "major") {
1505
+ const details = [];
1506
+ if (card.hebrew) details.push(card.hebrew);
1507
+ if (card.planet) details.push(`\u2609 ${card.planet}`);
1508
+ if (card.zodiac) details.push(`\u2648 ${card.zodiac}`);
1509
+ if (card.element) details.push(`\u25B3 ${card.element}`);
1510
+ if (details.length > 0) {
1511
+ lines.push(` ${chalk.dim(details.join(" | "))}`);
1512
+ }
1513
+ } else {
1514
+ const details = [];
1515
+ if (card.element) details.push(`${card.element}`);
1516
+ if (card.sephira) details.push(card.sephira);
1517
+ if (card.theme) details.push(card.theme);
1518
+ if (details.length > 0) {
1519
+ lines.push(` ${chalk.dim(details.join(" | "))}`);
1520
+ }
1521
+ }
1522
+ const keywords = card.reversed ? card.keywords_reversed : card.keywords_upright;
1523
+ if (keywords && keywords.length > 0) {
1524
+ const keywordStr = keywords.slice(0, 5).join(", ");
1525
+ lines.push(` ${chalk.italic(keywordStr)}`);
1526
+ }
1527
+ lines.push("");
1528
+ }
1529
+ lines.push(chalk.dim("\u2500".repeat(60)));
1530
+ lines.push(chalk.dim(" The cards are cast. The interpretation is yours."));
1531
+ lines.push("");
1532
+ return lines.join("\n");
1533
+ }
1534
+ function formatTarotCard(card) {
1535
+ const lines = [];
1536
+ const color = getTarotColor(card);
1537
+ lines.push("");
1538
+ lines.push(color(`\u{1F3B4} ${card.name}`));
1539
+ lines.push(` ${chalk.dim("Number:")} ${card.number} | ${chalk.dim("Arcana:")} ${card.arcana}`);
1540
+ if (card.arcana === "major") {
1541
+ if (card.hebrew) lines.push(` ${chalk.dim("Hebrew:")} ${card.hebrew} | ${chalk.dim("Path:")} ${card.path}`);
1542
+ if (card.planet) lines.push(` ${chalk.dim("Planet:")} ${card.planet}`);
1543
+ if (card.zodiac) lines.push(` ${chalk.dim("Zodiac:")} ${card.zodiac}`);
1544
+ if (card.element) lines.push(` ${chalk.dim("Element:")} ${card.element}`);
1545
+ } else {
1546
+ lines.push(` ${chalk.dim("Suit:")} ${card.suit} (${card.element})`);
1547
+ lines.push(` ${chalk.dim("Rank:")} ${card.rank} | ${chalk.dim("Sephira:")} ${card.sephira}`);
1548
+ lines.push(` ${chalk.dim("Theme:")} ${card.theme}`);
1549
+ }
1550
+ lines.push("");
1551
+ lines.push(chalk.bold.green(" Upright:"));
1552
+ lines.push(` ${card.keywords_upright.join(", ")}`);
1553
+ lines.push("");
1554
+ lines.push(chalk.bold.red(" Reversed:"));
1555
+ lines.push(` ${card.keywords_reversed.join(", ")}`);
1556
+ lines.push("");
1557
+ return lines.join("\n");
1558
+ }
1559
+ function formatTarotDeck(result) {
1560
+ const lines = [];
1561
+ lines.push("");
1562
+ lines.push(chalk.bold.hex("#9932CC")(`\u{1F3B4} TAROT DECK (${result.count} cards)`));
1563
+ if (result.filter) {
1564
+ lines.push(` Filter: ${result.filter}`);
1565
+ }
1566
+ lines.push("");
1567
+ const majors = result.cards.filter((c) => c.arcana === "major");
1568
+ const wands = result.cards.filter((c) => c.suit === "wands");
1569
+ const cups = result.cards.filter((c) => c.suit === "cups");
1570
+ const swords = result.cards.filter((c) => c.suit === "swords");
1571
+ const pentacles = result.cards.filter((c) => c.suit === "pentacles");
1572
+ if (majors.length > 0) {
1573
+ lines.push(TAROT_COLORS.major("\u2500\u2500 MAJOR ARCANA \u2500\u2500"));
1574
+ for (const card of majors) {
1575
+ lines.push(` ${String(card.number).padStart(2)}. ${card.name}`);
1576
+ }
1577
+ lines.push("");
1578
+ }
1579
+ const suits = [
1580
+ { name: "WANDS", cards: wands, color: TAROT_COLORS.wands, symbol: "\u{1F702}" },
1581
+ { name: "CUPS", cards: cups, color: TAROT_COLORS.cups, symbol: "\u{1F704}" },
1582
+ { name: "SWORDS", cards: swords, color: TAROT_COLORS.swords, symbol: "\u{1F701}" },
1583
+ { name: "PENTACLES", cards: pentacles, color: TAROT_COLORS.pentacles, symbol: "\u{1F703}" }
1584
+ ];
1585
+ for (const suit of suits) {
1586
+ if (suit.cards.length > 0) {
1587
+ lines.push(suit.color(`\u2500\u2500 ${suit.symbol} ${suit.name} \u2500\u2500`));
1588
+ for (const card of suit.cards) {
1589
+ lines.push(` ${String(card.number).padStart(2)}. ${card.name}`);
1590
+ }
1591
+ lines.push("");
1592
+ }
1593
+ }
1594
+ return lines.join("\n");
1595
+ }
1596
+ function formatTarotSpreads(result) {
1597
+ const lines = [];
1598
+ lines.push("");
1599
+ lines.push(chalk.bold.hex("#9932CC")("\u{1F3B4} AVAILABLE SPREADS"));
1600
+ lines.push("");
1601
+ for (const spread of result.spreads) {
1602
+ lines.push(chalk.bold(` ${spread.name} (${spread.id})`));
1603
+ lines.push(` ${chalk.dim(spread.description)}`);
1604
+ lines.push(` Cards: ${spread.count} \u2014 ${spread.positions.join(" \u2192 ")}`);
1605
+ lines.push("");
1606
+ }
1607
+ return lines.join("\n");
1608
+ }
1437
1609
 
1438
1610
  // src/types.ts
1439
1611
  function isError(result) {
@@ -1458,6 +1630,10 @@ export {
1458
1630
  moonExtended,
1459
1631
  transitScan,
1460
1632
  ephemerisMulti,
1633
+ tarotDraw,
1634
+ tarotCard,
1635
+ tarotDeck,
1636
+ tarotSpreads,
1461
1637
  getZodiacSymbol,
1462
1638
  getPlanetSymbol,
1463
1639
  getAspectSymbol,
@@ -1478,5 +1654,9 @@ export {
1478
1654
  formatMoonExtended,
1479
1655
  formatTransitScan,
1480
1656
  formatEphemerisMulti,
1657
+ formatTarotDraw,
1658
+ formatTarotCard,
1659
+ formatTarotDeck,
1660
+ formatTarotSpreads,
1481
1661
  isError
1482
1662
  };
package/dist/index.d.ts CHANGED
@@ -498,6 +498,59 @@ interface ThothError {
498
498
  }
499
499
  type ThothResult<T> = T | ThothError;
500
500
  declare function isError<T extends object>(result: ThothResult<T>): result is ThothError;
501
+ interface TarotCard {
502
+ number: number;
503
+ name: string;
504
+ arcana: 'major' | 'minor';
505
+ suit?: string;
506
+ rank?: string;
507
+ hebrew?: string;
508
+ path?: number;
509
+ element?: string;
510
+ planet?: string;
511
+ zodiac?: string;
512
+ domain?: string;
513
+ sephira?: string;
514
+ theme?: string;
515
+ keywords_upright: string[];
516
+ keywords_reversed: string[];
517
+ reversed?: boolean;
518
+ position?: number;
519
+ position_name?: string;
520
+ }
521
+ interface TarotDrawResult {
522
+ type: string;
523
+ timestamp: string;
524
+ entropy_source: string;
525
+ question?: string;
526
+ spread: string;
527
+ spread_name: string;
528
+ cards: TarotCard[];
529
+ total_cards: number;
530
+ }
531
+ interface TarotDrawOptions {
532
+ count?: number;
533
+ spread?: string;
534
+ question?: string;
535
+ reversals?: boolean;
536
+ }
537
+ interface TarotDeckResult {
538
+ type: string;
539
+ filter?: string;
540
+ count: number;
541
+ cards: TarotCard[];
542
+ }
543
+ interface TarotSpread {
544
+ id: string;
545
+ name: string;
546
+ count: number;
547
+ positions: string[];
548
+ description: string;
549
+ }
550
+ interface TarotSpreadsResult {
551
+ type: string;
552
+ spreads: TarotSpread[];
553
+ }
501
554
  interface ScoreOptions {
502
555
  year1: number;
503
556
  month1: number;
@@ -747,6 +800,22 @@ declare function transitScan(options: TransitScanOptions): Promise<ThothResult<T
747
800
  * Get multi-body ephemeris over a date range
748
801
  */
749
802
  declare function ephemerisMulti(options: EphemerisMultiOptions): Promise<ThothResult<EphemerisMultiResult>>;
803
+ /**
804
+ * Draw tarot cards with cryptographic randomness
805
+ */
806
+ declare function tarotDraw(options: TarotDrawOptions): Promise<ThothResult<TarotDrawResult>>;
807
+ /**
808
+ * Look up a specific tarot card
809
+ */
810
+ declare function tarotCard(identifier: string): Promise<ThothResult<TarotCard>>;
811
+ /**
812
+ * Get tarot deck (optionally filtered)
813
+ */
814
+ declare function tarotDeck(filter?: string): Promise<ThothResult<TarotDeckResult>>;
815
+ /**
816
+ * List available tarot spreads
817
+ */
818
+ declare function tarotSpreads(): Promise<ThothResult<TarotSpreadsResult>>;
750
819
 
751
820
  /**
752
821
  * Output formatting utilities
@@ -833,5 +902,21 @@ declare function formatTransitScan(result: any): string;
833
902
  * Format multi-body ephemeris
834
903
  */
835
904
  declare function formatEphemerisMulti(result: any): string;
905
+ /**
906
+ * Format a tarot draw result
907
+ */
908
+ declare function formatTarotDraw(result: any): string;
909
+ /**
910
+ * Format a single tarot card lookup
911
+ */
912
+ declare function formatTarotCard(card: any): string;
913
+ /**
914
+ * Format tarot deck listing
915
+ */
916
+ declare function formatTarotDeck(result: any): string;
917
+ /**
918
+ * Format available spreads
919
+ */
920
+ declare function formatTarotSpreads(result: any): string;
836
921
 
837
- export { type Aspect, type ChartOptions, type ChartResult, type CompositeOptions, type CompositeResult, type DirectedPlanet, type EphemerisMultiOptions, type EphemerisMultiResult, type EphemerisOptions, type EphemerisPosition, type EphemerisRangeOptions, type EphemerisRangeResult, type EphemerisResult, type HoraryHouse, type HoraryOptions, type HoraryResult, type House, type LunarPhase, type LunarReturnOptions, type LunarReturnResult, type MoonAspect, type MoonExtendedOptions, type MoonExtendedResult, type MoonOptions, type MoonResult, type Planet, type ProgressionsOptions, type ProgressionsResult, type RetrogradeStation, type ScoreOptions, type ScoreResult, type SignChange, type SolarArcOptions, type SolarArcResult, type SolarReturnOptions, type SolarReturnResult, type SynastryOptions, type SynastryResult, type ThothError, type ThothResult, type TransitOptions, type TransitResult, type TransitScanOptions, type TransitScanResult, chart, composite, ephemeris, ephemerisMulti, ephemerisRange, formatChart, formatComposite, formatDegrees, formatEphemeris, formatEphemerisMulti, formatEphemerisRange, formatHorary, formatLunarReturn, formatMoon, formatMoonExtended, formatProgressions, formatScore, formatSolarArc, formatSolarReturn, formatSynastry, formatTransitScan, formatTransits, getAspectSymbol, getPlanetSymbol, getZodiacSymbol, horary, isError, lunarReturn, moon, moonExtended, progressions, score, solarArc, solarReturn, synastry, transit, transitScan, version };
922
+ export { type Aspect, type ChartOptions, type ChartResult, type CompositeOptions, type CompositeResult, type DirectedPlanet, type EphemerisMultiOptions, type EphemerisMultiResult, type EphemerisOptions, type EphemerisPosition, type EphemerisRangeOptions, type EphemerisRangeResult, type EphemerisResult, type HoraryHouse, type HoraryOptions, type HoraryResult, type House, type LunarPhase, type LunarReturnOptions, type LunarReturnResult, type MoonAspect, type MoonExtendedOptions, type MoonExtendedResult, type MoonOptions, type MoonResult, type Planet, type ProgressionsOptions, type ProgressionsResult, type RetrogradeStation, type ScoreOptions, type ScoreResult, type SignChange, type SolarArcOptions, type SolarArcResult, type SolarReturnOptions, type SolarReturnResult, type SynastryOptions, type SynastryResult, type TarotCard, type TarotDeckResult, type TarotDrawOptions, type TarotDrawResult, type TarotSpread, type TarotSpreadsResult, type ThothError, type ThothResult, type TransitOptions, type TransitResult, type TransitScanOptions, type TransitScanResult, chart, composite, ephemeris, ephemerisMulti, ephemerisRange, formatChart, formatComposite, formatDegrees, formatEphemeris, formatEphemerisMulti, formatEphemerisRange, formatHorary, formatLunarReturn, formatMoon, formatMoonExtended, formatProgressions, formatScore, formatSolarArc, formatSolarReturn, formatSynastry, formatTarotCard, formatTarotDeck, formatTarotDraw, formatTarotSpreads, formatTransitScan, formatTransits, getAspectSymbol, getPlanetSymbol, getZodiacSymbol, horary, isError, lunarReturn, moon, moonExtended, progressions, score, solarArc, solarReturn, synastry, tarotCard, tarotDeck, tarotDraw, tarotSpreads, transit, transitScan, version };
package/dist/index.js CHANGED
@@ -19,6 +19,10 @@ import {
19
19
  formatSolarArc,
20
20
  formatSolarReturn,
21
21
  formatSynastry,
22
+ formatTarotCard,
23
+ formatTarotDeck,
24
+ formatTarotDraw,
25
+ formatTarotSpreads,
22
26
  formatTransitScan,
23
27
  formatTransits,
24
28
  getAspectSymbol,
@@ -34,10 +38,14 @@ import {
34
38
  solarArc,
35
39
  solarReturn,
36
40
  synastry,
41
+ tarotCard,
42
+ tarotDeck,
43
+ tarotDraw,
44
+ tarotSpreads,
37
45
  transit,
38
46
  transitScan,
39
47
  version
40
- } from "./chunk-QND56LGZ.js";
48
+ } from "./chunk-X7IGMJUH.js";
41
49
  export {
42
50
  chart,
43
51
  composite,
@@ -59,6 +67,10 @@ export {
59
67
  formatSolarArc,
60
68
  formatSolarReturn,
61
69
  formatSynastry,
70
+ formatTarotCard,
71
+ formatTarotDeck,
72
+ formatTarotDraw,
73
+ formatTarotSpreads,
62
74
  formatTransitScan,
63
75
  formatTransits,
64
76
  getAspectSymbol,
@@ -74,6 +86,10 @@ export {
74
86
  solarArc,
75
87
  solarReturn,
76
88
  synastry,
89
+ tarotCard,
90
+ tarotDeck,
91
+ tarotDraw,
92
+ tarotSpreads,
77
93
  transit,
78
94
  transitScan,
79
95
  version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-cli",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "𓅝 Astrological calculations from the command line. Swiss Ephemeris precision. Built for humans and agents.",
5
5
  "author": "AKLO <aklo@aklolabs.com>",
6
6
  "license": "MIT",