Back to Skills
    🦞

    skanetrafiken

    Skåne public transport trip planner (Skånetrafiken).

    By @rezkam
    View on GitHub
    SKILL.md
    ---
    name: skanetrafiken
    description: Skåne public transport trip planner (Skånetrafiken). Plans bus/train journeys with real-time delays. Supports stations, addresses, landmarks, and cross-border trips to Copenhagen.
    license: MIT
    compatibility: Requires curl, jq. Works with Claude Code and compatible agents.
    metadata:
      author: rezkam
      version: "1.2.0"
      region: sweden
    ---
    
    # Skånetrafiken Trip Planner
    
    Plan public transport journeys in Skåne, Sweden with real-time departure information.
    
    ## Commands
    
    ### 1. Search Location
    
    Search for stations, addresses, or points of interest.
    
    ```bash
    ./search-location.sh <query> [limit]
    ```
    
    | Argument | Description |
    |----------|-------------|
    | `query` | Location name to search for |
    | `limit` | Number of results to show (default: 3, max: 10) |
    
    **Output includes:**
    - `ID` - The location identifier (use this in journey search)
    - `Name` - Official name of the location
    - `Type` - STOP_AREA (station), ADDRESS, or POI (point of interest)
    - `Area` - Region/municipality
    - `Coordinates` - Latitude, longitude
    
    **When to increase limit:**
    - First result doesn't match user's intent
    - User's query is ambiguous (e.g., "station", "centrum")
    - Need to show user multiple options to choose from
    
    ### 2. Journey Search
    
    Plan a journey between two locations using their IDs.
    
    ```bash
    ./journey.sh <from-id> <from-type> <to-id> <to-type> [datetime] [mode]
    ```
    
    | Argument | Description |
    |----------|-------------|
    | `from-id` | Origin location ID (from search) or coordinates (`lat#lon`) |
    | `from-type` | `STOP_AREA`, `ADDRESS`, `POI`, or `LOCATION` (for coordinates) |
    | `to-id` | Destination location ID or coordinates |
    | `to-type` | Type of destination |
    | `datetime` | Optional: `"18:30"`, `"tomorrow 09:00"`, `"2026-01-15 09:00"` |
    | `mode` | Optional: `"depart"` (default) or `"arrive"` |
    
    **Important:** The Journey API only accepts `STOP_AREA` and `LOCATION` types. For `ADDRESS` or `POI` results, use the coordinates as `lat#lon` with type `LOCATION`.
    
    ---
    
    ## Understanding User Time Intent
    
    Before searching, understand what the user wants:
    
    ### Intent Types
    
    | User Says | Intent | How to Query |
    |-----------|--------|--------------|
    | "now", "next bus", "how do I get to" | **Travel Now** | No datetime parameter |
    | "in 30 minutes", "in 1 hour", "after lunch" | **Depart Later** | Calculate time, use `depart` mode |
    | "around 15:00", "sometime afternoon" | **Around Time** | Query with offset (see below) |
    | "arrive by 18:00", "need to be there at 9" | **Arrive By** | Use `arrive` mode |
    | "tomorrow morning", "on Friday at 10" | **Future Time** | Use specific datetime |
    
    ### Handling "Around Time" Queries
    
    When user wants options "around" a time, query 15-30 minutes earlier to show options before and after:
    
    ```bash
    # User: "I want to travel around 15:00"
    # Query at 14:30 to get options spanning 14:30-16:00+
    ./journey.sh ... "14:30" depart
    ```
    
    ### Relative Time Calculations
    
    Convert relative times to absolute:
    
    | User Says | Current: 14:00 | Query Time |
    |-----------|----------------|------------|
    | "in 30m" | → | "14:30" |
    | "in 1h" | → | "15:00" |
    | "in 2 hours" | → | "16:00" |
    
    ---
    
    ## LLM Response Formatting
    
    When presenting journey results to users, use these emojis and formatting guidelines.
    
    ### Emoji Reference
    
    | Emoji | Use For |
    |-------|---------|
    | 🚂 | Train (Pågatåg, Öresundståg) |
    | 🚌 | Bus |
    | 🚇 | Metro (Copenhagen) |
    | 🚋 | Tram |
    | ⛴️ | Ferry |
    | 🚶 | Walking segment |
    | ⏱️ | Time/duration |
    | 🕐 | Departure time |
    | 🏁 | Arrival time |
    | 📍 | Stop/station |
    | 🏠 | Origin (home/start) |
    | 🎯 | Destination |
    | ⚠️ | Delay or disruption |
    | ✅ | On time |
    | 🔄 | Transfer/change |
    | 🛤️ | Platform/track |
    
    ### Response Structure
    
    **Always include these key elements from the tool output:**
    
    1. **When to leave** - The actual time user needs to start (including walking)
    2. **Walking segments** - Distance and time for any walking
    3. **Transport departure** - When the bus/train actually leaves
    4. **Arrival time** - When user reaches destination
    5. **Any delays** - Show deviation from schedule
    
    ### Example Response Format
    
    **For a simple direct journey:**
    ```
    🏠 **Leave home at 09:00**
    
    🚶 Walk 450m to Möllevångstorget (5 min)
    
    📍 **Möllevångstorget** → 🎯 **Malmö C**
    🚌 Bus 5 departs 09:07 from Möllevångstorget
    🏁 Arrives 09:18 at Malmö C
    
    ⏱️ Total: 18 min
    ```
    
    **For a journey with transfer:**
    ```
    🏠 **Leave at 08:45**
    
    🚶 Walk 300m to Västra Hamnen (4 min)
    
    📍 **Västra Hamnen** → 🔄 **Malmö C** → 🎯 **Lund C**
    
    **Leg 1:**
    🚌 Bus 2 departs 08:51 [🛤️ Läge A]
    🏁 Arrives Malmö C 09:05
    
    🔄 Transfer at Malmö C (6 min)
    
    **Leg 2:**
    🚂 Pågatåg departs 09:11 [🛤️ Spår 4]
    🏁 Arrives Lund C 09:23
    
    ⏱️ Total: 38 min | 🔄 1 change
    ```
    
    **With delays:**
    ```
    🕐 **Depart 14:30** from Triangeln
    
    🚂 Öresundståg 1042 → København H
    ⚠️ +8 min delay (expected 14:38 instead of 14:30)
    🏁 Arrives ~15:25 (normally 15:17)
    ```
    
    ### Walking Segment Details
    
    **CRITICAL: Always show walking details from the tool output:**
    
    - Distance in meters (from `line.distance`)
    - Include walking in the "leave time" calculation
    - Show walking at start AND end of journey
    
    Example tool output:
    ```
    → WALK 450m from Kalendegatan to Möllevångstorget
    ```
    
    Format as:
    ```
    🚶 Walk 450m to Möllevångstorget (~5 min)
    ```
    
    Walk time estimate: ~100m per minute (normal walking speed)
    
    ### Presenting Multiple Options
    
    When showing journey options, make timing crystal clear:
    
    ```
    I found 3 options for you:
    
    **Option 1 - Leave now (09:00)** ✅ Recommended
    🚶 5 min walk → 🚌 Bus 5 at 09:07 → arrives 09:25
    ⏱️ Total: 25 min
    
    **Option 2 - Leave in 15m (09:15)**
    🚶 5 min walk → 🚌 Bus 5 at 09:22 → arrives 09:40
    ⏱️ Total: 25 min
    
    **Option 3 - Leave in 30m (09:30)**
    🚶 5 min walk → 🚂 Train at 09:37 → arrives 09:48
    ⏱️ Total: 18 min | Faster but later departure
    ```
    
    ### Time Offset Notation
    
    Use clear notation for departure times:
    
    | Notation | Meaning |
    |----------|---------|
    | "now" | Immediately |
    | "in 15m" | 15 minutes from now |
    | "in 1h" | 1 hour from now |
    | "at 14:30" | Specific time |
    
    ---
    
    ## LLM Workflow: How to Plan a Trip
    
    Follow this workflow when a user asks for a trip:
    
    ### Step 1: Understand Time Intent
    
    Parse what the user wants:
    - **"How do I get to..."** → Travel now
    - **"I need to be there at 18:00"** → Arrive mode
    - **"Sometime around 3pm"** → Query 14:30, show range
    - **"In about an hour"** → Calculate from current time
    
    ### Step 2: Search for Both Locations
    
    Search for origin and destination separately:
    
    ```bash
    ./search-location.sh "Malmö C"
    ./search-location.sh "Emporia"
    ```
    
    ### Step 3: Validate Search Results
    
    **Check each result carefully:**
    
    1. **Exact or close match?** - If the name matches what the user asked for, proceed.
    
    2. **Multiple results returned?** - The script shows up to 10 matches. If the first result isn't clearly correct, ask the user to confirm.
    
    3. **Name significantly different?** - If user asked for "the mall near Hyllie" and result shows "Emporia", confirm with user: "I found Emporia shopping center near Hyllie. Is this correct?"
    
    4. **No results found?** - Try alternative strategies (see below).
    
    ### Step 4: Handle Ambiguous or Failed Searches
    
    **When results don't match or are ambiguous, ask clarifying questions:**
    
    ```
    I searched for "centrum" and found multiple locations:
    1. Malmö Centrum (bus stop)
    2. Lund Centrum (bus stop)
    3. Helsingborg Centrum (bus stop)
    
    Which one did you mean?
    ```
    
    **When no results are found, try these strategies:**
    
    1. **Try with city name for addresses:**
       ```bash
       # If "Storgatan 10" fails, try:
       ./search-location.sh "Storgatan 10, Malmö"
       ```
    
    2. **Try official station names:**
       ```bash
       # If "Malmö station" fails, try:
       ./search-location.sh "Malmö C"
       ```
    
    3. **Try landmark name only (without city):**
       ```bash
       # If "Emporia, Malmö" fails, try:
       ./search-location.sh "Emporia"
       ```
    
    4. **Use coordinates as last resort:**
       - If you know the approximate location, use `lat#lon` format directly
       - Ask user: "I couldn't find that location. Can you provide the address or coordinates?"
    
    ### Step 5: Convert Types for Journey API
    
    The Journey API only accepts:
    - `STOP_AREA` - Bus/train stations (use ID directly)
    - `LOCATION` - GPS coordinates as `lat#lon`
    
    **If search returns ADDRESS or POI:**
    - Use the coordinates from search result
    - Format as `lat#lon` with type `LOCATION`
    
    Example:
    ```bash
    # Search returns: ID: 123, Type: ADDRESS, Coordinates: 55.605, 13.003
    # Use in journey as:
    ./journey.sh "55.605#13.003" LOCATION 9021012080000000 STOP_AREA
    ```
    
    ### Step 6: Execute Journey Search
    
    Once you have confirmed IDs/coordinates for both locations:
    
    ```bash
    ./journey.sh <from-id> <from-type> <to-id> <to-type> [datetime] [mode]
    ```
    
    ### Step 7: Format Response with Emojis
    
    Use the emoji guide above to present results clearly. **Always use actual numbers from the tool output - never speculate or estimate.**
    
    ---
    
    ## Query Formatting Rules
    
    **The search API is sensitive to formatting. Follow these rules:**
    
    ### Landmarks and POIs: Name Only
    
    Use the landmark name WITHOUT city name.
    
    ```bash
    # CORRECT
    ./search-location.sh "Emporia"
    ./search-location.sh "Triangeln"
    ./search-location.sh "Turning Torso"
    
    # WRONG - city name breaks POI search
    ./search-location.sh "Emporia, Malmö"        # May return wrong location!
    ./search-location.sh "Triangeln, Malmö"      # Unnecessary, may fail
    ```
    
    ### Street Addresses: Include City
    
    Include city name for better accuracy.
    
    ```bash
    # CORRECT
    ./search-location.sh "Kalendegatan 12, Malmö"
    ./search-location.sh "Storgatan 25, Lund"
    ./search-location.sh "Drottninggatan 5, Helsingborg"
    
    # RISKY - may be ambiguous
    ./search-location.sh "Kalendegatan 12"       # Works if unambiguous
    ```
    
    ### Train Stations: Use Official Names
    
    Use "C" suffix for central stations.
    
    ```bash
    # CORRECT
    ./search-location.sh "Malmö C"
    ./search-location.sh "Lund C"
    ./search-location.sh "Helsingborg C"
    ./search-location.sh "Malmö Hyllie"
    ./search-location
    
    ... (truncated)