Skill: alanburchill/translink-cli (version 1.0.1)

--- name: translink-cli description: Query, troubleshoot, and explain Translink SEQ GTFS static + realtime data using local translink_* commands or plugin slash commands. Use for schedule lookups, stop/route/trip joins, vehicle/trip realtime checks, alerts, schema drift review, PK/FK reasoning, and paginated filtering. --- # Translink CLI Skill Use when working with Translink data in this environment. ## Prerequisite This skill requires the Translink CLI scripts to be installed and available in PATH. - CLI repo: `https://github.com/alanburchill/traslink-cli-scripts` - Expected commands: `translink_*` (or equivalent wrappers that expose the same command names) If the CLI is not installed, stop and ask the user to install it first. ## Command surfaces - Shell CLI: `translink_*` - Plugin slash commands: `/translink_*` and `/translink <command> [args...]` ## Core workflow 1. Refresh or validate cache/schema with `translink_schedule_refresh` when freshness is uncertain. 2. Query with shared parameters (`--where`, `--contains`, `--in`, `--page`, `--per-page`, etc.). 3. On strict field errors, use fuzzy suggestions in the JSON error payload to auto-correct. 4. Use PK/FK references for joins across routes/trips/stops/stop_times/calendar/shapes. 5. For authoritative current schema, read generated schema docs first. ## Shared parameter contract All commands support: - `--where field=value` (repeatable) - `--contains field=text` (repeatable) - `--in field=v1,v2,...` (repeatable) - `--fields a,b,c` - `--sort field` - `--order asc|desc` - `--page N` - `--per-page N` (default 20) - `--format table|json|csv` - `--count-only` Realtime extras: - `--expand` (include nested JSON fields) - `--raw` (include full raw entity JSON) - `--time epoch|iso` Schedule extras: - `--refresh` - `--schema` ## Runtime behavior - Static cache: `~/.openclaw/cache/translink/` - TTL: 24h - Daily refresh cron (example): 5:00 AM local time (`translink:schedule-refresh`) - Refresh lock prevents concurrent extract races. - Schema is header-driven and auto-adapts to added columns. ## Read these references as needed - `references/commands.md` — command/param/error contract - `references/usage.md` — examples - `references/relationships.md` — PK/FK joins - `references/schema-generated.md` — auto-generated live schema (authoritative) - `references/column-meanings.md` — GTFS field semantics

path: references/schema.md
content: # Translink GTFS schema (current feed)

Source: `~/.openclaw/cache/translink/current/*.txt`

Only columns currently present in feed are documented below.

## Data format rules

- IDs (`*_id`) are opaque strings; compare as exact text.
- Dates in static GTFS are `YYYYMMDD`.
- Times in `stop_times` are `HH:MM:SS` (may exceed 24h in GTFS generally).
- Lat/lon are decimal degrees.
- Enums are often numeric strings in CSV.

---

## agency.txt
Columns:
- `agency_id` (string, PK-ish in feed)
- `agency_name` (text)
- `agency_url` (URL)
- `agency_timezone` (IANA tz)
- `agency_lang` (language code)
- `agency_phone` (text)

Keys:
- PK: `agency_id` (feed-level unique expected)
- FK target from `routes.agency_id`

## calendar.txt
Columns:
- `service_id` (string)
- `monday`..`sunday` (`0|1`)
- `start_date` (`YYYYMMDD`)
- `end_date` (`YYYYMMDD`)

Keys:
- PK: `service_id`
- FK target from `trips.service_id`

## calendar_dates.txt
Columns:
- `service_id` (string)
- `date` (`YYYYMMDD`)
- `exception_type` (`1`=added service, `2`=removed service)

Keys:
- Composite key (practical): `service_id + date`
- FK: `service_id -> calendar.service_id` (or standalone service when calendar omitted)

## feed_info.txt
Columns:
- `feed_publisher_name` (text)
- `feed_publisher_url` (URL)
- `feed_lang` (language code)
- `feed_start_date` (`YYYYMMDD`)
- `feed_end_date` (`YYYYMMDD`)

Keys:
- Usually one-row metadata table.

## routes.txt
Columns:
- `route_id` (string)
- `agency_id` (string)
- `route_short_name` (text)
- `route_long_name` (text)
- `route_desc` (text)
- `route_type` (GTFS route type enum)
- `route_url` (URL)
- `route_color` (hex without `#`)
- `route_text_color` (hex without `#`)

Keys:
- PK: `route_id`
- FK: `agency_id -> agency.agency_id`
- FK target from `trips.route_id`

## shapes.txt
Columns:
- `shape_id` (string)
- `shape_pt_lat` (float)
- `shape_pt_lon` (float)
- `shape_pt_sequence` (int, ordering)

Keys:
- Composite key: `shape_id + shape_pt_sequence`
- FK target from `trips.shape_id`

## stops.txt
Columns:
- `stop_id` (string)
- `stop_code` (text)
- `stop_name` (text)
- `stop_desc` (text)
- `stop_lat` (float)
- `stop_lon` (float)
- `zone_id` (string)
- `stop_url` (URL)
- `location_type` (enum, e.g. stop/station)
- `parent_station` (string stop_id)
- `platform_code` (text)

Keys:
- PK: `stop_id`
- Self-FK: `parent_station -> stops.stop_id`
- FK target from `stop_times.stop_id`

## stop_times.txt
Columns:
- `trip_id` (string)
- `arrival_time` (`HH:MM:SS`)
- `departure_time` (`HH:MM:SS`)
- `stop_id` (string)
- `stop_sequence` (int)
- `pickup_type` (enum)
- `drop_off_type` (enum)
- `timepoint` (enum)

Keys:
- Composite key: `trip_id + stop_sequence`
- FK: `trip_id -> trips.trip_id`
- FK: `stop_id -> stops.stop_id`

## trips.txt
Columns:
- `route_id` (string)
- `service_id` (string)
- `trip_id` (string)
- `trip_headsign` (text)
- `direction_id` (enum)
- `block_id` (string)
- `shape_id` (string)

Keys:
- PK: `trip_id`
- FK: `route_id -> routes.route_id`
- FK: `service_id -> calendar.service_id`
- FK: `shape_id -> shapes.shape_id`

---

## Core join map (PK/FK)

- `routes.route_id = trips.route_id`
- `trips.trip_id = stop_times.trip_id`
- `stops.stop_id = stop_times.stop_id`
- `trips.service_id = calendar.service_id`
- `calendar.service_id = calendar_dates.service_id`
- `trips.shape_id = shapes.shape_id`
- `routes.agency_id = agency.agency_id`
- `stops.parent_station = stops.stop_id` (self join)

## Realtime normalized output fields

### translink_tripupdates
- `entity_id`, `trip_id`, `route_id`, `start_time`, `start_date`, `schedule_relationship`, `vehicle_id`, `vehicle_label`, `stop_time_updates_count`, `timestamp`

### translink_vehiclepositions
- `entity_id`, `vehicle_id`, `vehicle_label`, `trip_id`, `route_id`, `current_stop_sequence`, `stop_id`, `current_status`, `timestamp`, `latitude`, `longitude`, `bearing`, `speed`, `occupancy_status`

### translink_alerts
- `entity_id`, `informed_entities_count`, `active_period_start`, `active_period_end`, `cause`, `effect`, `severity_level`, `header`, `description`, `url`


path: references/column-meanings.md
content: # Column Meanings + Data Format (Current Static Feed)

This maps the currently-present columns to GTFS meaning and expected format.

## agency.txt

| Column | Format | Meaning |
|---|---|---|
| `agency_id` | integer/string id | Unique agency key; joins with `routes.agency_id`. |
| `agency_name` | text | Public agency name. |
| `agency_url` | URL | Agency website. |
| `agency_timezone` | IANA tz string | Timezone for agency times. |
| `agency_lang` | BCP-47/lang code | Default language for text fields. |
| `agency_phone` | text | Customer contact phone. |

## calendar.txt

| Column | Format | Meaning |
|---|---|---|
| `service_id` | string id | Service pattern key; joins with `trips.service_id`. |
| `monday`..`sunday` | 0/1 integer | Whether service normally runs on that weekday. |
| `start_date` | YYYYMMDD | First date this weekly pattern is active. |
| `end_date` | YYYYMMDD | Last date this weekly pattern is active. |

## calendar_dates.txt

| Column | Format | Meaning |
|---|---|---|
| `service_id` | string id | Service key affected by exception. |
| `date` | YYYYMMDD | Exception date. |
| `exception_type` | enum int | `1` add service, `2` remove service. |

## feed_info.txt

| Column | Format | Meaning |
|---|---|---|
| `feed_publisher_name` | text | Feed publisher name. |
| `feed_publisher_url` | URL | Feed publisher URL. |
| `feed_lang` | lang code | Default language for feed text. |
| `feed_start_date` | YYYYMMDD | Earliest date covered by this feed. |
| `feed_end_date` | YYYYMMDD | Latest date covered by this feed. |

## routes.txt

| Column | Format | Meaning |
|---|---|---|
| `route_id` | string id | Unique route key; joins to `trips.route_id`. |
| `agency_id` | id | Owning agency (`agency.agency_id`). |
| `route_short_name` | text/number | Public short route label/number. |
| `route_long_name` | text | Public long route name/description line. |
| `route_desc` | text | Optional route description text. |
| `route_type` | enum int | GTFS mode (e.g., bus/tram/train/ferry). |
| `route_url` | URL | Route info page. |
| `route_color` | RRGGBB | Route branding color (hex, no #). |
| `route_text_color` | RRGGBB | Preferred text color on route color. |

## shapes.txt

| Column | Format | Meaning |
|---|---|---|
| `shape_id` | id | Shape key referenced by `trips.shape_id`. |
| `shape_pt_lat` | float | Point latitude. |
| `shape_pt_lon` | float | Point longitude. |
| `shape_pt_sequence` | integer | Point order along the polyline. |

## stop_times.txt

| Column | Format | Meaning |
|---|---|---|
| `trip_id` | id | Trip key (`trips.trip_id`). |
| `arrival_time` | HH:MM:SS | Scheduled arrival at stop. |
| `departure_time` | HH:MM:SS | Scheduled departure from stop. |
| `stop_id` | id | Stop key (`stops.stop_id`). |
| `stop_sequence` | integer | Sequence of stop within trip. |
| `pickup_type` | enum int | Pickup policy at stop (regular/no pickup/etc.). |
| `drop_off_type` | enum int | Drop-off policy at stop. |
| `timepoint` | enum int | Whether time is exact timepoint vs approximate. |

## stops.txt

| Column | Format | Meaning |
|---|---|---|
| `stop_id` | id | Unique stop/platform/station key. |
| `stop_code` | text | Rider-facing short stop code. |
| `stop_name` | text | Public stop/station name. |
| `stop_desc` | text | Optional extra stop description. |
| `stop_lat` | float | Latitude. |
| `stop_lon` | float | Longitude. |
| `zone_id` | id | Fare/zone identifier. |
| `stop_url` | URL | Stop information page. |
| `location_type` | enum int | Stop/station type (platform/station/etc.). |
| `parent_station` | id | Parent station for child stops/platforms. |
| `platform_code` | text | Platform/bay code shown to riders. |

## trips.txt

| Column | Format | Meaning |
|---|---|---|
| `route_id` | id | Route key (`routes.route_id`). |
| `service_id` | id | Service pattern (`calendar.service_id`). |
| `trip_id` | id | Unique trip key; joins to `stop_times.trip_id`. |
| `trip_headsign` | text | Rider-facing destination/headsign. |
| `direction_id` | 0/1 int | Direction variant (agency-defined semantics). |
| `block_id` | id | Vehicle block/interlining key. |
| `shape_id` | id | Shape key (`shapes.shape_id`). |


path: references/schema-generated.md
content: # Translink Schema (Auto-generated)

Generated: 2026-02-22T21:42:51.496Z
Schema version: `ea229eefe06a0e11`

## Drift since previous snapshot

- No schema changes detected.

## PK/FK relationships

- **agency.txt**
  - PK: agency_id
  - FK: (none)
- **calendar.txt**
  - PK: service_id
  - FK: (none)
- **calendar_dates.txt**
  - PK: service_id, date
  - FK: service_id -> calendar.service_id
- **feed_info.txt**
  - PK: (none/metadata)
  - FK: (none)
- **routes.txt**
  - PK: route_id
  - FK: agency_id -> agency.agency_id
- **shapes.txt**
  - PK: shape_id, shape_pt_sequence
  - FK: (none)
- **stops.txt**
  - PK: stop_id
  - FK: parent_station -> stops.stop_id
- **stop_times.txt**
  - PK: trip_id, stop_sequence
  - FK: trip_id -> trips.trip_id; stop_id -> stops.stop_id
- **trips.txt**
  - PK: trip_id
  - FK: route_id -> routes.route_id; service_id -> calendar.service_id; shape_id -> shapes.shape_id

## agency.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| agency_id | integer | int | no | Agency identifier (joined by routes.agency_id). | 10 · 11 · 12 |
| agency_name | string | text | no | Public agency name. | Mt Gravatt Coach & Travel · Transdev · Park Ridge Transit |
| agency_url | string | url | no | Agency website URL. | http://www.mtgcoach.com.au/ · https://www.transdevbrisbane.com.au/ · https://www.busqld.com.au/ |
| agency_timezone | string | text | no | Agency timezone (IANA). | Australia/Brisbane |
| agency_lang | string | text | no | Default language code. | en |
| agency_phone | string | text | yes | Agency contact phone. | 07 3808 7800 · 07 3248 6100 · 07 3802 1233 |

## calendar.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| service_id | string | text | no | Service pattern identifier (joined by trips.service_id). | GCLR 25_26-39424 · GCLR 25_26-39425 · GCLR 25_26-39426 |
| monday | integer | 0|1 | no | Service runs Monday (0/1). | 0 · 1 |
| tuesday | integer | 0|1 | no | Service runs Tuesday (0/1). | 0 · 1 |
| wednesday | integer | 0|1 | no | Service runs Wednesday (0/1). | 0 · 1 |
| thursday | integer | 0|1 | no | Service runs Thursday (0/1). | 0 · 1 |
| friday | integer | 0|1 | no | Service runs Friday (0/1). | 1 · 0 |
| saturday | integer | 0|1 | no | Service runs Saturday (0/1). | 0 · 1 |
| sunday | integer | 0|1 | no | Service runs Sunday (0/1). | 0 · 1 |
| start_date | string | YYYYMMDD | no | Service start date (YYYYMMDD). | 20260227 · 20260223 · 20260221 |
| end_date | string | YYYYMMDD | no | Service end date (YYYYMMDD). | 20260417 · 20260422 · 20260418 |

## calendar_dates.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| service_id | string | text | no | Service identifier. | BBL 25_26-39417 · BCC 25_26-39837 · BCC 25_26-39840 |
| date | string | YYYYMMDD | no | Exception date (YYYYMMDD). | 20260403 · 20260406 · 20260404 |
| exception_type | string | mixed | no | 1=added service, 2=removed service. | 2 · 1 |

## feed_info.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| feed_publisher_name | string | text | no | Feed publisher name. | Department of Transport and Main Roads - Translink Division |
| feed_publisher_url | string | url | no | Feed publisher URL. | https://www.translink.com.au/ |
| feed_lang | string | text | no | Feed default language code. | en |
| feed_start_date | string | YYYYMMDD | no | Feed coverage start date (YYYYMMDD). | 20260221 |
| feed_end_date | string | YYYYMMDD | no | Feed coverage end date (YYYYMMDD). | 20260422 |

## routes.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| route_id | string | text | no | Route identifier (joined by trips.route_id). | 19-4660 · 19-4762 · 26-4660 |
| agency_id | integer | int | no | Agency identifier (agency.agency_id). | 4 · 11 · 10 |
| route_short_name | string | text | no | Public route short name. | 19 · 26 · 29 |
| route_long_name | string | text | no | Public route long name. | Salisbury - PA Hospital StationLink · Rocklea - PA Hospital StationLink · Upper Mt Gravatt - RBWH via Fortitude Valley |
| route_desc | text | empty | yes | Route description text. | - |
| route_type | string | mixed | no | GTFS route type enum. | 3 · 2 · 4 |
| route_url | string | url | no | Route URL. | https://jp.translink.com.au/plan-your-journey/timetables/bus/T/19 · https://jp.translink.com.au/plan-your-journey/timetables/bus/T/26 · https://jp.translink.com.au/plan-your-journey/timetables/bus/T/29 |
| route_color | string | text | no | Hex route color (without #). | E463A4 · FFD51F · D20000 |
| route_text_color | string | text | no | Hex text color (without #). | 000000 · FFFFFF |

## shapes.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| shape_id | integer | int | no | Shape identifier (joined by trips.shape_id). | 190011 · 190012 · 190013 |
| shape_pt_lat | float | float | no | Shape point latitude. | -27.553364 · -27.553313 · -27.553222 |
| shape_pt_lon | float | float | no | Shape point longitude. | 153.023933 · 153.023604 · 153.023007 |
| shape_pt_sequence | integer | int | no | Shape point order within shape_id. | 10001 · 10002 · 10003 |

## stop_times.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| trip_id | string | text | no | Trip identifier (trips.trip_id). | 35827515-ATS_HBL 26-41689 · 35827516-ATS_HBL 26-41689 · 35827517-ATS_HBL 26-41689 |
| arrival_time | string | HH:MM:SS | no | Arrival time HH:MM:SS. | 04:56:00 · 05:00:00 · 05:04:00 |
| departure_time | string | HH:MM:SS | no | Departure time HH:MM:SS. | 04:56:00 · 05:00:00 · 05:04:00 |
| stop_id | integer | int | no | Stop identifier (stops.stop_id). | 11329 · 3246 · 320365 |
| stop_sequence | string | mixed | no | Order within trip. | 1 · 2 · 3 |
| pickup_type | integer | 0|1 | no | Pickup behavior enum. | 0 · 1 |
| drop_off_type | integer | 0|1 | no | Drop-off behavior enum. | 0 · 1 |
| timepoint | integer | 0|1 | no | Timepoint indicator enum. | 1 · 0 |

## stops.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| stop_id | string | mixed | no | Stop identifier (joined by stop_times.stop_id). | 1 · 10 · 100 |
| stop_code | integer | int | no | Public stop code. | 000001 · 000010 · 000100 |
| stop_name | string | text | no | Stop public name. | Herschel Street Stop 1 near North Quay · Ann Street Stop 11 at King George Square · Margaret St stop 93 at George St |
| stop_desc | text | empty | yes | Stop description. | - |
| stop_lat | string | text | no | Stop latitude. |  -27.467834 ·  -27.468003 ·  -27.473751 |
| stop_lon | string | text | no | Stop longitude. |  153.019079 ·  153.023970 ·  153.026745 |
| zone_id | integer | 0|1 | no | Fare zone identifier. | 1 |
| stop_url | string | url | yes | Stop URL. | https://translink.com.au/stop/000001/gtfs/ · https://translink.com.au/stop/000010/gtfs/ · https://translink.com.au/stop/000100/gtfs/ |
| location_type | integer | 0|1 | no | Stop/station type enum. | 0 |
| parent_station | string | text | yes | Parent station stop_id (self join). | place_qsbs · place_inteno · place_wynsta |
| platform_code | string | text | yes | Platform code/name. | 1e · 1f · 1g |

## trips.txt

| column | inferred_type | format | nullable | purpose | examples |
|---|---|---|---|---|---|
| route_id | string | text | no | Route identifier (routes.route_id). | R348-3745 · R609-4398 · R616-4398 |
| service_id | string | text | no | Service identifier (calendar.service_id). | ATS_HBL 26-41689 · ATS_HBL 26-41691 · ATS_KBL 26-41826 |
| trip_id | string | text | no | Trip identifier (joined by stop_times.trip_id). | 35827515-ATS_HBL 26-41689 · 35827516-ATS_HBL 26-41689 · 35827517-ATS_HBL 26-41689 |
| trip_headsign | string | text | no | Trip destination/sign text. | Northgate station · Shorncliffe station · Caboolture station |
| direction_id | integer | 0|1 | no | Direction enum. | 0 · 1 |
| block_id | text | empty | yes | Block identifier. | - |
| shape_id | string | text | no | Shape identifier (shapes.shape_id). | R3480261 · R3480260 · R6090044 |


path: references/usage.md
content: # Translink CLI usage

## Static schedule examples

```bash
translink_schedule_routes --page 1 --per-page 20
translink_schedule_stops --where stop_id=120002 --fields stop_id,stop_name,stop_lat,stop_lon
translink_schedule_stops --where stop_id=010824 --fields stop_id,stop_name,stop_lat,stop_lon
translink_schedule_routes --contains route_long_name=stationlink --page 1 --per-page 10
translink_schedule_routes --where route_short_name=M1 --fields route_id,route_short_name,route_long_name
translink_schedule_trips --in direction_id=0,1 --sort trip_id --order asc --page 1 --per-page 10
translink_schedule_routes --schema
```

## Realtime examples

```bash
translink_tripupdates --page 1 --per-page 10 --time iso
translink_tripupdates --expand --fields entity_id,trip_id,route_id,timestamp,stop_time_updates_json --page 1 --per-page 5 --format json
translink_vehiclepositions --raw --fields entity_id,vehicle_id,raw_json --page 1 --per-page 3 --format json
translink_alerts --contains header=closure --expand --time iso --page 1 --per-page 10
```

## Plugin slash command examples

```text
/translink_schedule_routes --page 1 --per-page 5
/translink translink_tripupdates --page 1 --per-page 3 --time iso
```

## Refresh + schema drift

```bash
translink_schedule_refresh
```

Returns:
- `schema_version`
- `drift[]` (added/removed/type changes)
- generated schema-doc locations

## Invalid field recovery

```bash
translink_schedule_routes --where routeid=19
```

Returns `INVALID_FIELD` with fuzzy suggestions (e.g., `route_id`).


path: references/schema-static.md
content: # Translink GTFS Static Schema (Current Feed)

## agency.txt

| Column | Observed type | Notes |
|---|---|---|
| `agency_id` | `integer` | |
| `agency_name` | `string` | |
| `agency_url` | `url` | |
| `agency_timezone` | `string` | |
| `agency_lang` | `string` | |
| `agency_phone` | `string` | |

## calendar.txt

| Column | Observed type | Notes |
|---|---|---|
| `service_id` | `string` | |
| `monday` | `integer` | |
| `tuesday` | `integer` | |
| `wednesday` | `integer` | |
| `thursday` | `integer` | |
| `friday` | `integer` | |
| `saturday` | `integer` | |
| `sunday` | `integer` | |
| `start_date` | `date_yyyymmdd` | |
| `end_date` | `date_yyyymmdd` | |

## calendar_dates.txt

| Column | Observed type | Notes |
|---|---|---|
| `service_id` | `string` | |
| `date` | `date_yyyymmdd` | |
| `exception_type` | `integer` | |

## feed_info.txt

| Column | Observed type | Notes |
|---|---|---|
| `feed_publisher_name` | `string` | |
| `feed_publisher_url` | `url` | |
| `feed_lang` | `string` | |
| `feed_start_date` | `date_yyyymmdd` | |
| `feed_end_date` | `date_yyyymmdd` | |

## routes.txt

| Column | Observed type | Notes |
|---|---|---|
| `route_id` | `string` | |
| `agency_id` | `integer` | |
| `route_short_name` | `integer` | |
| `route_long_name` | `string` | |
| `route_desc` | `string` | |
| `route_type` | `integer` | |
| `route_url` | `url` | |
| `route_color` | `color_hex` | |
| `route_text_color` | `color_hex` | |

## shapes.txt

| Column | Observed type | Notes |
|---|---|---|
| `shape_id` | `integer` | |
| `shape_pt_lat` | `float` | |
| `shape_pt_lon` | `float` | |
| `shape_pt_sequence` | `integer` | |

## stop_times.txt

| Column | Observed type | Notes |
|---|---|---|
| `trip_id` | `string` | |
| `arrival_time` | `time_hhmmss` | |
| `departure_time` | `time_hhmmss` | |
| `stop_id` | `integer` | |
| `stop_sequence` | `integer` | |
| `pickup_type` | `integer` | |
| `drop_off_type` | `integer` | |
| `timepoint` | `integer` | |

## stops.txt

| Column | Observed type | Notes |
|---|---|---|
| `stop_id` | `integer` | |
| `stop_code` | `integer` | |
| `stop_name` | `string` | |
| `stop_desc` | `string` | |
| `stop_lat` | `float` | |
| `stop_lon` | `float` | |
| `zone_id` | `integer` | |
| `stop_url` | `url` | |
| `location_type` | `integer` | |
| `parent_station` | `string` | |
| `platform_code` | `string` | |

## trips.txt

| Column | Observed type | Notes |
|---|---|---|
| `route_id` | `string` | |
| `service_id` | `string` | |
| `trip_id` | `string` | |
| `trip_headsign` | `string` | |
| `direction_id` | `integer` | |
| `block_id` | `string` | |
| `shape_id` | `string` | |


path: references/relationships.md
content: # GTFS Relationships (Current Files)

## Primary keys (practical)

- `agency.txt`: `agency_id`
- `routes.txt`: `route_id`
- `trips.txt`: `trip_id`
- `stops.txt`: `stop_id`
- `shapes.txt`: composite (`shape_id`, `shape_pt_sequence`)
- `stop_times.txt`: composite (`trip_id`, `stop_sequence`)
- `calendar.txt`: `service_id`
- `calendar_dates.txt`: composite (`service_id`, `date`)
- `feed_info.txt`: single-row metadata (no PK required)

## Foreign keys

- `routes.agency_id` -> `agency.agency_id`
- `trips.route_id` -> `routes.route_id`
- `trips.service_id` -> `calendar.service_id` (and `calendar_dates.service_id`)
- `trips.shape_id` -> `shapes.shape_id`
- `stop_times.trip_id` -> `trips.trip_id`
- `stop_times.stop_id` -> `stops.stop_id`

## Common joins

1. Service pattern for a route:
   - `routes` -> `trips` -> `stop_times` -> `stops`
2. Day-of-operation filter:
   - `trips.service_id` with `calendar` + `calendar_dates`
3. Shape path for a trip:
   - `trips.shape_id` -> `shapes.shape_id`


path: references/commands.md
content: # Translink CLI Commands

## Surfaces

- Shell: `translink_*`
- Plugin slash: `/translink_*`
- Aggregated plugin command: `/translink <command> [args...]`

## Schedule (static GTFS)

- `translink_schedule_agency`
- `translink_schedule_calendar`
- `translink_schedule_calendar_dates`
- `translink_schedule_feed_info`
- `translink_schedule_routes`
- `translink_schedule_shapes`
- `translink_schedule_stops`
- `translink_schedule_stop_times`
- `translink_schedule_trips`
- `translink_schedule_refresh`

## Realtime (GTFS-RT)

- `translink_tripupdates`
- `translink_vehiclepositions`
- `translink_alerts`

## Shared parameters (all commands)

- `--where field=value` (repeatable)
- `--contains field=text` (repeatable)
- `--in field=v1,v2,...` (repeatable)
- `--fields a,b,c`
- `--sort field`
- `--order asc|desc` (default `asc`)
- `--page N` (default `1`)
- `--per-page N` (default `20`, max `200`)
- `--format table|json|csv` (default `table`)
- `--count-only`
- `--help`

Schedule extras:
- `--refresh` force static cache refresh first
- `--schema` print current columns (+ inferred details when available)

Realtime extras:
- `--expand` add nested JSON expansion fields
- `--raw` add full raw entity JSON per row
- `--time epoch|iso` render timestamps as epoch (default) or ISO

## Strict LLM-friendly error contract

Invalid fields return structured JSON:
- `error.code`
- `error.message`
- `error.invalid`
- `error.suggestions` (fuzzy)
- `error.valid_fields`
- `error.example`

## Success response contract

List responses:
- `data: []`
- `meta.page`
- `meta.per_page`
- `meta.total`
- `meta.total_pages`
- `meta.has_next`


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: clean (LOW)