Resolve a natural-language origin + destination + (optional) arrive-by / leave-at time into the public-transport itineraries returned by transportnsw.info: per-itinerary departure / arrival times, duration, leg-by-leg mode + route, fare, real-time delay status. Drives the deterministic URL-param surface; falls back to the form when location IDs aren't yet cached. Read-only.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionfind-transport-routeExecute the skills CLI command in your project's root directory to begin installation:
Fetches find-transport-route from transportnsw.info/find-transport-route-yas5pc and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate find-transport-route. Access via /find-transport-route in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| name | find-transport-route |
| title | Transport NSW Trip Planner — Find a Route |
| description | >- Resolve a natural-language origin + destination + (optional) arrive-by / leave-at time into the public-transport itineraries returned by transportnsw.info: per-itinerary departure / arrival times, duration, leg-by-leg mode + route, fare, real-time delay status. Drives the deterministic URL-param surface; falls back to the form when location IDs aren't yet cached. Read-only. |
| website | transportnsw.info |
| category | transit |
| tags | - transit - trip-planner - public-transport - sydney - nsw - read-only - url-param |
| source | 'browserbase: agent-runtime 2026-05-20' |
| updated | '2026-05-20' |
| recommended_method | url-param |
| alternative_methods | - method: browser rationale: >- Drive the typeahead + form when stop / suburb IDs are not yet cached for a given origin or destination string. The URL-param surface needs the resolved IDs as input, and the typeahead modal is the only public way to discover them. Persist resolved IDs to a local cache so each location is resolved exactly once. - method: api rationale: >- Transport for NSW publishes an official OAuth-gated Trip Planner REST API at opendata.transport.nsw.gov.au. Use it when the caller has a registered API key — it is the canonical machine surface. For unauthenticated agents the API returns 401/403, and the URL-param path on transportnsw.info documented here is the cheapest deterministic alternative. |
| verified | true |
| proxies | true |
Given a natural-language trip query — origin + destination + (optional) arrival/departure time — return the public-transport itineraries offered by the official NSW trip planner: each itinerary's departure time, arrival time, duration, leg-by-leg mode + route number, transfer count, walk time, fare, and real-time delay status. Read-only — never books, never opens a checkout flow (the planner has no checkout — only journey suggestions).
The Transport NSW trip planner accepts the full origin / destination / time triple via URL query parameters on https://transportnsw.info/trip-planner/plan. A single GET reproduces the same state the UI would reach after five clicks, so the recommended path is to (1) resolve each location string to a stop / suburb ID via the typeahead, then (2) construct the canonical URL.
The Browser fallback (driving the form click-by-click) is documented at the end and is what you should use when you don't yet have IDs cached.
https://transportnsw.info/trip-planner/plan
?from=<originId>
&to=<destinationId>
[&arrivalDateTime=YYYYMMDDHHMM] # arrive-by; Sydney local time
[&departureDateTime=YYYYMMDDHHMM] # leave-at; Sydney local time
[&excludedModes=<csv-of-mode-ids>] # e.g. 11 = school bus, auto-added by the "Plan a trip" splash button
arrivalDateTime and departureDateTime → "Leaving now" (server uses Sydney current time, not the browser's clock).from and to:
200060 = Central Station, Sydney.suburbID:<int>:1:<URL-encoded-label>:<x>:<y>:GDAV. Example: suburbID:95361002:1:Bondi+Beach:4895254:3758264:GDAV. Use this when the user names a suburb / POI rather than a specific stop — the planner routes to a representative point in the suburb.arrivalDateTime / departureDateTime are in YYYYMMDDHHMM and must be interpreted in Australia/Sydney local time (not the browser's TZ — see gotcha). A value in the past returns an empty alert ("No results found"), not an error.Example: Central → Bondi Beach arriving by 17:00 Wed 20 May 2026:
https://transportnsw.info/trip-planner/plan?from=200060&to=suburbID:95361002:1:Bondi+Beach:4895254:3758264:GDAV&arrivalDateTime=202605201700
When the user names an origin or destination without a cached ID, drive the search modal once and harvest the URL the planner produces:
browse open https://transportnsw.info/trip-planner/planbrowse click @<ref of "Origin: No location selected"> — opens the search modal.browse click @<ref of textbox "Search input"> then browse type "<location string>".browse wait timeout 2500 — typeahead is debounced.browse get url — the new URL contains the resolved from= (or to=) ID. Cache it; the IDs are stable across sessions.The same typeahead is what you'd use to discover new IDs at runtime; once resolved, they should be persisted in a local cache so a CI test never re-discovers them.
The cleanest path is to bypass the UI date picker entirely and pass arrivalDateTime / departureDateTime in the URL (see §1). If for some reason you must drive the picker:
browse click @<ref of "Selected time: Leaving now"> — opens the "Choose date and time" dialog.browse click @<ref of "Select Arrive by option"> (or "Select Leave at option").Day, Hour, Minute) are custom listboxes, not native <select> — browse select will return selected: []. Instead, click the combobox to open it, then click the desired option ref. Available values:
Today (<weekday>), Tomorrow (<weekday>), then absolute dates DD MMM (<weekday>) for ~14 days ahead.00–23 (24-hour).00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 (5-minute granularity only).browse click @<ref of "Apply"> — the URL now carries arrivalDateTime= / departureDateTime= and results refresh in ~2–4 s.Once the planner has both endpoints + a valid time, the results panel renders a vertical list of button: elements — one per itinerary. Parse each button's aria-label — it's a structured, comma-separated string that enumerates every field cleanly:
"Leaving in <N> minutes
Transfer to <mode-1> Transfer to <mode-2> Walk for <N>min
<interchange-stop>
Departing at HH:MM, Duration is N minutes, Arriving at HH:MM[, next day]
Fare is $X.XX
[On-time | <N> min late | Real-time unavailable]
from <first-stop>, Platform <N>
This service is Accessible
There is an alert for this service"
Each leg is one Transfer to <mode> <route-number> clause (e.g. Transfer to T4 train, Transfer to 379 bus). Walking legs are Walk for <N>min. The final segment usually ends with the interchange stop name (e.g. Bondi Junction).
The same data appears as child StaticText nodes (16:22, 34min, $5.63, ...) but those are formatted in the browser's local TZ, while the aria-label is in Sydney AEST. Always parse the aria-label for deterministic output. (See gotchas.)
Above the list, four tabs gate the mode set: Public Transport (default) / Walk / Cycle / Drive. The Drive tab returns a single car-route summary, not a list — keep the Public Transport tab selected unless the user explicitly asked for driving or active-transport directions.
sid=$(browse cloud sessions create --keep-alive --verified --proxies | …)
export BROWSE_SESSION="$sid"
browse open "https://transportnsw.info/trip-planner/plan" --remote
browse wait load --remote && browse wait timeout 2000 --remote
# Origin
browse click @<ref "Origin: No location selected">
browse click @<ref "Search input"> && browse type "Central Station" --remote
browse wait timeout 2500 --remote
browse click @<ref of first matching result> # URL gets ?from=200060
# Destination
browse click @<ref "Destination: No location selected">
browse click @<ref "Search input"> && browse type "Bondi Beach" --remote
browse wait timeout 2500 --remote
browse click @<ref of first matching result> # URL gets &to=suburbID:…
# Time (optional)
browse click @<ref "Selected time: Leaving now">
browse click @<ref "Select Arrive by option">
browse click @<ref Day combobox> ; browse click @<ref "Tomorrow (Wed)">
browse click @<ref Hour combobox> ; browse click @<ref "17">
browse click @<ref Minute combobox>; browse click @<ref "00">
browse click @<ref "Apply">
# Read results
browse snapshot --remote # parse button aria-labels (see §4)
The first-page render after Apply takes 2–4 s; browse wait timeout 4000 after the Apply click before snapshotting is reliable. A stealth + residential-proxy session (--verified --proxies) is what was used during skill development and is the safer default; the site is fronted by CloudFront but does not appear to gate on bot-detection for this surface.
aria-label on each itinerary button uses Sydney AEST (UTC+10), but the visible StaticText nodes (the 16:22, 34min, 23:55 strings) use the browser session's local timezone. Verified on a Browserbase US-West session (PDT, UTC-7): aria-label "Departing at 16:22" vs StaticText "23:22" — a 17-hour offset for the same departure. Always parse the aria-label; treat the StaticText fields as display chrome, not data. If you must use StaticText, force the session TZ via Australia/Sydney. CI tests should pin the session to Sydney TZ to make the StaticText and aria-label converge.arrivalDateTime / departureDateTime are in Sydney local time, not the browser's clock. A value in the past returns the empty alert: "No results found / There were no services found" panel — there is no explicit error message. If the planner returns "No results" for a route you know is well-served (e.g. Central → Bondi Beach), the most common cause is a stale arrivalDateTime whose date is already in Sydney's past.<select> elements. browse select @<ref> <value> returns selected: [] and silently does nothing. Click the combobox first, then click the option ref inside the resulting listbox. Minutes are 5-minute increments only (00, 05, 10, …, 55).from and to accept two distinct ID shapes — a 6-digit numeric stop ID (e.g. 200060 = Central Station) or a structured suburb / place ID suburbID:<int>:1:<URL-encoded-label>:<x>:<y>:GDAV (e.g. suburbID:95361002:1:Bondi+Beach:4895254:3758264:GDAV). Both from and to accept either shape independently. Picking a "Stop" in the typeahead yields the numeric shape; picking a "Place" yields the suburb shape.excludedModes=11 is auto-injected by the splash "Plan a trip" button. Mode 11 appears to be school-bus services. Directly hitting /trip-planner/plan?from=…&to=… without excludedModes includes all modes, which is usually what you want. Other mode IDs (deduced from the "Mode (7)" filter chip showing 7 modes — Train, Metro, Bus, Light rail, Ferry, Coach, School bus): pass as comma-separated, e.g. excludedModes=4,9 to exclude Light rail and Ferry.button: Selected trip preference: Earliest arrival chip on the results page — there is no tripPref= query param.from and to are set — there is no explicit "Search" / "Submit" button on the form. The "Updated: HH:MM" button in the results panel is a refresh button, not a submit.[3-2451] div: Bondi Beach) is the suburb (Places tab); the next two are bus stops named "Bondi Beach" (Stops tab). Use the Places tab when the user said "Bondi Beach" generically, and the Stops tab when they specified a stop ID / station./trip or /trip-planner as the entry URL — both render a marketing splash with a "Plan a trip" button, not the form. Open /trip-planner/plan directly to skip the splash. (Hitting /trip-planner/plan with no params lands on the empty form, ready for input — equivalent to clicking the splash button.)opendata.transport.nsw.gov.au (TfNSW Open Data Hub) — if the calling agent has a registered API key, prefer that over scraping. For unauthenticated agents, the URL-param surface documented here is the cheapest deterministic path. Don't waste cycles trying to hit the API anonymously./sapi-style public JSON behind the page. The site is a SPA that calls authenticated TfNSW backends; cookie-less direct hits against the internal XHR endpoints return 401/403. The accessibility-tree-driven scrape of aria-label strings is the supported public surface.{
"query": {
"origin": { "raw": "Central Station", "id": "200060", "resolved_label": "Central Station, Sydney" },
"destination": { "raw": "Bondi Beach", "id": "suburbID:95361002:1:Bondi+Beach:4895254:3758264:GDAV", "resolved_label": "Bondi Beach" },
"time_anchor": { "mode": "arrive_by", "datetime_local": "2026-05-20T17:00", "tz": "Australia/Sydney" }
},
"url": "https://transportnsw.info/trip-planner/plan?from=200060&to=suburbID:95361002:1:Bondi+Beach:4895254:3758264:GDAV&arrivalDateTime=202605201700",
"itineraries": [
{
"depart_local": "16:22",
"arrive_local": "16:56",
"next_day": false,
"duration_min": 34,
"fare_aud": 5.63,
"transfers": 1,
"walk_min": 6,
"realtime_status": "Real-time unavailable",
"first_stop": "Central Station, Platform 24",
"interchange": "Bondi Junction",
"accessible": true,
"alerts": true,
"legs": [
{ "mode": "train", "route": "T4" },
{ "mode": "bus", "route": "379" },
{ "mode": "walk", "duration_min": 6 }
]
}
],
"result_status": "ok"
}
Distinct outcome shapes:
// ok — one or more itineraries returned
{ "result_status": "ok", "itineraries": [ ... ] }
// empty — planner returned the "No results found" alert (most often: arrivalDateTime in the past, or genuinely unreachable)
{ "result_status": "no_results", "itineraries": [], "alert_text": "There were no services found. Refine your preferences and try again." }
// ambiguous_location — the typeahead returned 0 matches or multiple equally-ranked matches for an origin/destination string
{ "result_status": "ambiguous_location", "field": "destination", "raw": "...", "candidates": [ { "label": "...", "id": "..." }, ... ] }
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
booksearanchescape.escapia.com/find-sea-ranch-house-sffj18
booking.com/search-hotels-asq6cc
nav.com/get-smb-funding-2s1rpm
aliexpress.com/search-product-p0h8a7
ruwangi.com/ruwangi-parfum-laki-laki-ko0z5t
shopee.com.my/search-products-5epzg0
Keeps context tight: find-transport-route is the kind of skill you can hand to a new teammate without a long onboarding doc.
find-transport-route is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
Registry listing for find-transport-route matched our evaluation — installs cleanly and behaves as described in the markdown.
find-transport-route fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Useful defaults in find-transport-route — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
We added find-transport-route from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
Registry listing for find-transport-route matched our evaluation — installs cleanly and behaves as described in the markdown.
find-transport-route fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Keeps context tight: find-transport-route is the kind of skill you can hand to a new teammate without a long onboarding doc.
Registry listing for find-transport-route matched our evaluation — installs cleanly and behaves as described in the markdown.
showing 1-10 of 75