From 0670f9606270af2f768ca2ef7eaa51980e0310bb Mon Sep 17 00:00:00 2001 From: Hikari Date: Tue, 17 Mar 2026 09:35:41 -0700 Subject: [PATCH] feat(tarot): expand spread descriptions and add good-for guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each spread now has a fuller description and a "Good for:" line explaining what kinds of questions it suits best. ✨ This commit was made with love from Hikari~ 🌸 --- tarot/generate.py | 157 +++++++ tarot/index.html | 1069 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1226 insertions(+) create mode 100644 tarot/generate.py create mode 100644 tarot/index.html diff --git a/tarot/generate.py b/tarot/generate.py new file mode 100644 index 0000000..3654fb1 --- /dev/null +++ b/tarot/generate.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +"""Generate position-specific tarot card meanings for all 78 cards across all spreads.""" + +import json +import os +import time +import anthropic + +client = anthropic.Anthropic(api_key="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") + +CARDS = [ + "the_fool", "the_magician", "the_high_priestess", "the_empress", "the_emperor", + "the_hierophant", "the_lovers", "the_chariot", "strength", "the_hermit", + "wheel_of_fortune", "justice", "the_hanged_man", "death", "temperance", + "the_devil", "the_tower", "the_star", "the_moon", "the_sun", + "judgement", "the_world", + "ace_of_wands", "two_of_wands", "three_of_wands", "four_of_wands", "five_of_wands", + "six_of_wands", "seven_of_wands", "eight_of_wands", "nine_of_wands", "ten_of_wands", + "page_of_wands", "knight_of_wands", "queen_of_wands", "king_of_wands", + "ace_of_cups", "two_of_cups", "three_of_cups", "four_of_cups", "five_of_cups", + "six_of_cups", "seven_of_cups", "eight_of_cups", "nine_of_cups", "ten_of_cups", + "page_of_cups", "knight_of_cups", "queen_of_cups", "king_of_cups", + "ace_of_swords", "two_of_swords", "three_of_swords", "four_of_swords", "five_of_swords", + "six_of_swords", "seven_of_swords", "eight_of_swords", "nine_of_swords", "ten_of_swords", + "page_of_swords", "knight_of_swords", "queen_of_swords", "king_of_swords", + "ace_of_pentacles", "two_of_pentacles", "three_of_pentacles", "four_of_pentacles", "five_of_pentacles", + "six_of_pentacles", "seven_of_pentacles", "eight_of_pentacles", "nine_of_pentacles", "ten_of_pentacles", + "page_of_pentacles", "knight_of_pentacles", "queen_of_pentacles", "king_of_pentacles", +] + +POSITIONS = { + "single": "The Card (Single Card Draw)", + "three-card-past": "Past (Three Card Spread)", + "three-card-present": "Present (Three Card Spread)", + "three-card-future": "Future (Three Card Spread)", + "love-personalities": "Separate Personalities (Three Card Love Spread)", + "love-common-base": "Common Base of the Relationship (Three Card Love Spread)", + "love-connection": "The Binding Connection (Three Card Love Spread)", + "five-card-situation": "The Current Situation (Five Card Spread)", + "five-card-response": "The Response (Five Card Spread)", + "five-card-holding-back": "What Is Holding You Back (Five Card Spread)", + "five-card-change": "What You Can Do to Change the Situation (Five Card Spread)", + "five-card-outcome": "The Outcome If You Make That Change (Five Card Spread)", + "compat-your-mind": "Your Mind / Crown Chakra (Compatibility H Spread)", + "compat-your-heart": "Your Heart Chakra (Compatibility H Spread)", + "compat-your-root": "Your Root Chakra / Sexual Compatibility (Compatibility H Spread)", + "compat-bridge": "What Keeps You Together (Compatibility H Spread)", + "compat-their-mind": "Their Mind / Crown Chakra (Compatibility H Spread)", + "compat-their-heart": "Their Heart Chakra (Compatibility H Spread)", + "compat-their-root": "Their Root Chakra / Sexual Compatibility (Compatibility H Spread)", + "horseshoe-1": "Position 1: The Past (Horseshoe Spread)", + "horseshoe-2": "Position 2: The Present (Horseshoe Spread)", + "horseshoe-3": "Position 3: Hidden Influences (Horseshoe Spread)", + "horseshoe-4": "Position 4: The Querent (Horseshoe Spread)", + "horseshoe-5": "Position 5: Attitudes of Others (Horseshoe Spread)", + "horseshoe-6": "Position 6: What Should Be Done (Horseshoe Spread)", + "horseshoe-7": "Position 7: The Likely Outcome (Horseshoe Spread)", + "astro-aries": "Aries — House of Self (Astrological Spread)", + "astro-taurus": "Taurus — House of Possessions (Astrological Spread)", + "astro-gemini": "Gemini — House of Communication (Astrological Spread)", + "astro-cancer": "Cancer — House of Home (Astrological Spread)", + "astro-leo": "Leo — House of Pleasure (Astrological Spread)", + "astro-virgo": "Virgo — House of Health & Service (Astrological Spread)", + "astro-libra": "Libra — House of Partnerships (Astrological Spread)", + "astro-scorpio": "Scorpio — House of Transformation (Astrological Spread)", + "astro-sagittarius": "Sagittarius — House of Philosophy (Astrological Spread)", + "astro-capricorn": "Capricorn — House of Career (Astrological Spread)", + "astro-aquarius": "Aquarius — House of Community (Astrological Spread)", + "astro-pisces": "Pisces — House of the Unconscious (Astrological Spread)", + "celtic-present": "The Present Situation (Celtic Cross)", + "celtic-challenge": "The Challenge / Crossing Card (Celtic Cross)", + "celtic-past": "The Recent Past (Celtic Cross)", + "celtic-future": "The Near Future (Celtic Cross)", + "celtic-above": "Above — Conscious Goal (Celtic Cross)", + "celtic-below": "Below — Subconscious Influences (Celtic Cross)", + "celtic-advice": "Advice (Celtic Cross)", + "celtic-external": "External Influences (Celtic Cross)", + "celtic-hopes": "Hopes and Fears (Celtic Cross)", + "celtic-outcome": "The Final Outcome (Celtic Cross)", +} + +def card_display_name(card_key: str) -> str: + return card_key.replace("_", " ").title() + +def generate_meanings(card: str, positions: dict) -> dict: + card_name = card_display_name(card) + positions_list = "\n".join( + f'- "{key}": {label}' for key, label in positions.items() + ) + + position_properties = { + key: { + "type": "object", + "properties": { + "regular": {"type": "string", "description": f"Upright meaning of {card_name} in the {label} position"}, + "inverted": {"type": "string", "description": f"Reversed meaning of {card_name} in the {label} position"}, + }, + "required": ["regular", "inverted"], + } + for key, label in positions.items() + } + + tool = { + "name": "save_card_meanings", + "description": "Save position-specific tarot card meanings", + "input_schema": { + "type": "object", + "properties": position_properties, + "required": list(positions.keys()), + }, + } + + response = client.messages.create( + model="claude-haiku-4-5-20251001", + max_tokens=8192, + tools=[tool], + tool_choice={"type": "tool", "name": "save_card_meanings"}, + messages=[{ + "role": "user", + "content": ( + f'You are a knowledgeable tarot reader. Generate specific, meaningful 2-3 sentence interpretations ' + f'for the tarot card "{card_name}" in each spread position. Each interpretation must be tailored to ' + f'the card\'s traditional symbolism and the specific role of that position.\n\nPositions:\n{positions_list}' + ), + }], + ) + + tool_use_block = next(b for b in response.content if b.type == "tool_use") + return tool_use_block.input + +def main(): + output_dir = os.path.join(os.path.dirname(__file__), "cards") + os.makedirs(output_dir, exist_ok=True) + + for i, card in enumerate(CARDS): + output_path = os.path.join(output_dir, f"{card}.json") + if os.path.exists(output_path): + print(f"[{i+1}/{len(CARDS)}] Skipping {card} (already exists)") + continue + + print(f"[{i+1}/{len(CARDS)}] Generating {card}...") + try: + meanings = generate_meanings(card, POSITIONS) + with open(output_path, "w", encoding="utf-8") as f: + json.dump(meanings, f, indent=2, ensure_ascii=False) + print(f" ✓ Saved {card}.json") + except Exception as e: + print(f" ✗ Error for {card}: {e}") + + # Small delay to be kind to the API + if i < len(CARDS) - 1: + time.sleep(0.5) + + print("\nDone!") + +if __name__ == "__main__": + main() diff --git a/tarot/index.html b/tarot/index.html new file mode 100644 index 0000000..806f7ad --- /dev/null +++ b/tarot/index.html @@ -0,0 +1,1069 @@ + + + + Tarot Reading + + + + + + + +
+
+

🔮 Tarot Reading

+

Draw your cards and receive guidance from the arcana.

+
+ +
+

Choose your spread:

+
+ + + + + + + + +
+

A single card drawn to offer guidance or a focus for your day.

+

Good for: Daily check-ins, meditation focus, or a gentle nudge when you need clarity.

+ +
+ +
+
+
+
+
+
+
+ + + +