{"id":"ef1d80e1-393b-44b7-97ef-68a7e05b9359","entityType":"agent","slug":"clawhub-khj809-srt","name":"SRT","canonicalUrl":"https://www.xpersona.co/agent/clawhub-khj809-srt","canonicalPath":"/agent/clawhub-khj809-srt","generatedAt":"2026-10-10T08:37:56.149Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":null},"description":"Korean SRT (Super Rapid Train) search, reservation, and booking management Skill: SRT Owner: khj809 Summary: Korean SRT (Super Rapid Train) search, reservation, and booking management Tags: latest:1.1.1 Version history: v1.1.1 | 2026-02-21T15:28:02.899Z | user Fix cron delivery for isolated sessions - Replace --announce delivery with --no-deliver + explicit message tool call - Avoids gateway closed (1008): pairing required error in isolated cron sessions - Update SKILL.md Step 3/4 with CLI-","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2.1K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s174pdvs14war16p83z8wekpf583pp3j:srt","sourceUrl":"https://clawhub.ai/khj809/srt","homepage":"https://clawhub.ai/khj809/skills/srt","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/khj809/srt","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/khj809/skills/srt","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":67,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Korean SRT (Super Rapid Train) search, reservation, and booking management Skill: SRT Owner: khj809 Summary: Korean SRT (Super Rapid Train) search, reservation,"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":null},"stars":null,"forks":null,"downloads":2148,"packageName":null,"latestVersion":"1.1.1","tractionLabel":"2.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T18:16:04.314Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T18:16:04.338Z","lastCrawledAt":"2026-10-09T18:16:04.314Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T18:16:04.314Z","lastVerifiedAt":null,"highlights":[{"version":"1.1.1","createdAt":"2026-02-21T15:28:02.899Z","changelog":"Fix cron delivery for isolated sessions - Replace `--announce` delivery with `--no-deliver` + explicit `message` tool call - Avoids `gateway closed (1008): pairing required` error in isolated cron sessions - Update SKILL.md Step 3/4 with CLI-based cron examples and delivery guidance","fileCount":7,"zipByteSize":18203},{"version":"1.1.0","createdAt":"2026-02-19T11:07:58.441Z","changelog":"CLI restructure + codebase consolidation - Rename `search_trains.py` → `train.py`; consolidate `make_reservation.py`, `view_bookings.py`, `cancel_booking.py`, `check_retry_log.py` → `reserve.py` - All reservation logic (`run_one_shot`, `run_retry`, `run_list`, `run_cancel`, `run_status`, `run_stop`, `run_log`) lives in `reserve.py` - Extract `fetch_trains_from_cache()` into `train.py`; delegates to `search_trains()` — removes duplicate SRT API call - `utils.load_search_results()` replaced by `load_search_cache()` (file I/O only; no SRT calls) - `srt_cli.py` is now a pure router with no inline business logic - Update SKILL.md: remove `make_reservation.py` references; fix `reserve retry` option table","fileCount":6,"zipByteSize":16642},{"version":"1.0.0","createdAt":"2026-02-18T07:26:33.710Z","changelog":"Security hardening + SKILL.md refactor - Replace `pickle` with JSON for search result caching (removes RCE-class deserialization risk) - Add `os.chmod(0o600)` on all created files (log, cache, rate-limit state) - Add `get_data_dir()` via `SRT_DATA_DIR` env var — removes hardcoded `~/.openclaw/tmp/srt` path - Add `--log-file` arg to `make_reservation.py`; prints `LOG_FILE: <path>` at startup - Add `requires.env` metadata for `SRT_PHONE`/`SRT_PASSWORD` (fixes ClawHub security scan mismatch) - Add SRTrain PyPI/GitHub source URL to install spec - Compact `SKILL.md`: add Continuous Monitoring architecture, remove non-skill content","fileCount":9,"zipByteSize":18984},{"version":"0.1.3","createdAt":"2026-02-03T05:02:35.252Z","changelog":"- **0.1.3** - Retry improvements and monitoring requirements - Unified `reserve` command with `--retry` flag - Added `--timeout-minutes` for time-based retry limits (default: 60) - Added `--train-id` support for comma-separated multiple trains (e.g., \"1,3,5\") - Changed `--wait-seconds` default from 20 to 10 seconds - Search includes sold-out trains by default (`available_only=False`) - **Monitoring:** Isolated session + agentTurn cron jobs required for background retry","fileCount":9,"zipByteSize":20675},{"version":"0.1.2","createdAt":"2026-02-02T09:25:02.645Z","changelog":"- Add `--all` flag for sold-out trains - Search now supports `--all` to include sold-out trains (passes `available_only=False`)","fileCount":8,"zipByteSize":16337},{"version":"0.1.1","createdAt":"2026-02-02T08:19:35.985Z","changelog":"- Updated all CLI usage examples to require the `uv run --with SRTrain` command prefix for correct dependency handling. - No feature or functional changes to the skill logic or tools. - Improved clarity for setup and command usage to match installation requirements.","fileCount":8,"zipByteSize":16096},{"version":"0.1.0","createdAt":"2026-02-02T08:12:26.620Z","changelog":"- Initial release of the SRT skill for Korean high-speed rail management. - Enables searching, booking, viewing, and canceling SRT train reservations via OpenClaw, CLI, or AI orchestration. - Includes rate limiting and retry protections to guard SRT accounts. - Supports natural language and slash command use with Korean station names. - Provides actionable error messages and clear output in JSON format for easy integration.","fileCount":8,"zipByteSize":16077}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s174pdvs14war16p83z8wekpf583pp3j:srt","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T08:37:56.146Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-khj809-srt/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":null},"readme":"Skill: SRT\n\nOwner: khj809\n\nSummary: Korean SRT (Super Rapid Train) search, reservation, and booking management\n\nTags: latest:1.1.1\n\nVersion history:\n\nv1.1.1 | 2026-02-21T15:28:02.899Z | user\n\nFix cron delivery for isolated sessions\n  - Replace `--announce` delivery with `--no-deliver` + explicit `message` tool call\n  - Avoids `gateway closed (1008): pairing required` error in isolated cron sessions\n  - Update SKILL.md Step 3/4 with CLI-based cron examples and delivery guidance\n\nv1.1.0 | 2026-02-19T11:07:58.441Z | user\n\nCLI restructure + codebase consolidation\n  - Rename `search_trains.py` → `train.py`; consolidate `make_reservation.py`, `view_bookings.py`, `cancel_booking.py`, `check_retry_log.py` → `reserve.py`\n  - All reservation logic (`run_one_shot`, `run_retry`, `run_list`, `run_cancel`, `run_status`, `run_stop`, `run_log`) lives in `reserve.py`\n  - Extract `fetch_trains_from_cache()` into `train.py`; delegates to `search_trains()` — removes duplicate SRT API call\n  - `utils.load_search_results()` replaced by `load_search_cache()` (file I/O only; no SRT calls)\n  - `srt_cli.py` is now a pure router with no inline business logic\n  - Update SKILL.md: remove `make_reservation.py` references; fix `reserve retry` option table\n\nv1.0.0 | 2026-02-18T07:26:33.710Z | user\n\nSecurity hardening + SKILL.md refactor\n  - Replace `pickle` with JSON for search result caching (removes RCE-class deserialization risk)\n  - Add `os.chmod(0o600)` on all created files (log, cache, rate-limit state)\n  - Add `get_data_dir()` via `SRT_DATA_DIR` env var — removes hardcoded `~/.openclaw/tmp/srt` path\n  - Add `--log-file` arg to `make_reservation.py`; prints `LOG_FILE: <path>` at startup\n  - Add `requires.env` metadata for `SRT_PHONE`/`SRT_PASSWORD` (fixes ClawHub security scan mismatch)\n  - Add SRTrain PyPI/GitHub source URL to install spec\n  - Compact `SKILL.md`: add Continuous Monitoring architecture, remove non-skill content\n\nv0.1.3 | 2026-02-03T05:02:35.252Z | user\n\n- **0.1.3** - Retry improvements and monitoring requirements\n  - Unified `reserve` command with `--retry` flag\n  - Added `--timeout-minutes` for time-based retry limits (default: 60)\n  - Added `--train-id` support for comma-separated multiple trains (e.g., \"1,3,5\")\n  - Changed `--wait-seconds` default from 20 to 10 seconds\n  - Search includes sold-out trains by default (`available_only=False`)\n  - **Monitoring:** Isolated session + agentTurn cron jobs required for background retry\n\nv0.1.2 | 2026-02-02T09:25:02.645Z | user\n\n- Add `--all` flag for sold-out trains\n  - Search now supports `--all` to include sold-out trains (passes `available_only=False`)\n\nv0.1.1 | 2026-02-02T08:19:35.985Z | user\n\n- Updated all CLI usage examples to require the `uv run --with SRTrain` command prefix for correct dependency handling.\n- No feature or functional changes to the skill logic or tools.\n- Improved clarity for setup and command usage to match installation requirements.\n\nv0.1.0 | 2026-02-02T08:12:26.620Z | user\n\n- Initial release of the SRT skill for Korean high-speed rail management.\n- Enables searching, booking, viewing, and canceling SRT train reservations via OpenClaw, CLI, or AI orchestration.\n- Includes rate limiting and retry protections to guard SRT accounts.\n- Supports natural language and slash command use with Korean station names.\n- Provides actionable error messages and clear output in JSON format for easy integration.\n\nArchive index:\n\nArchive v1.1.1: 7 files, 18203 bytes\n\nFiles: scripts/reserve.py (15869b), scripts/srt_cli.py (7040b), scripts/train.py (5301b), scripts/utils.py (13731b), skill-card.md (2423b), SKILL.md (7558b), _meta.json (122b)\n\nFile v1.1.1:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"], \"env\": [\"SRT_PHONE\", \"SRT_PASSWORD\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain from PyPI (uv) — source: https://pypi.org/project/SRTrain / https://github.com/ryanking13/SRT\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\n## Prerequisites\n\n- Environment variables `SRT_PHONE` (format: `010-XXXX-XXXX`) and `SRT_PASSWORD` must be set before running scripts.\n\n## Reference\n\n**Environment variables:**\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `SRT_PHONE` | ✅ | SRT account phone number (hyphens required: `010-XXXX-XXXX`) |\n| `SRT_PASSWORD` | ✅ | SRT account password |\n| `SRT_DATA_DIR` | optional | Directory for logs, cache, and state files. Defaults to system temp dir (`/tmp/srt`). |\n\n**Station names** (Korean only):\n수서, 부산, 동대구, 대전, 천안아산, 오송, 광주송정, 울산, 포항, 경주, 김천구미, 익산, 전주, 목포, 신경주\n\n**Date:** `YYYYMMDD` · **Time:** `HHMMSS` (e.g. `200000` = 20:00)\n\n---\n\n## Commands\n\n### Search Trains\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nSearch params and results are cached (in `SRT_DATA_DIR`) and required by `reserve`.\n\n### Reserve (one-shot)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve one-shot --train-id \"1\"\n```\n`--train-id` is the 1-based index from search results. Must run `train search` first.\n\n### View Reservations\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve list --format json\n```\n\n### Cancel Reservation\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve cancel \\\n  --reservation-id \"RES123456\" --confirm\n```\n\n---\n\n## Continuous Monitoring (취소표 모니터링)\n\nFor \"keep trying until a seat opens\" requests, **do not loop inside a cron job**.\nInstead: run `srt_cli.py reserve retry` as a persistent background process, then create a separate cron job to read the log and report.\n\n### Step 1: Search (populate cache)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nNote the `train_id` of the target train from the results.\n\n### Step 2: Start background retry process\n```bash\nLOG_FILE=<choose_any_path>.log\nPID_FILE=<choose_any_path>.pid\ncd <project_dir> && nohup uv run --with SRTrain python3 scripts/srt_cli.py reserve retry \\\n  --train-id <id> --timeout-minutes 1440 --wait-seconds 10 \\\n  --log-file \"$LOG_FILE\" > /dev/null 2>&1 &\necho $! > \"$PID_FILE\"\n```\n\nThe script prints `LOG_FILE: <path>` on startup — capture this to know exactly where logs are written.\nYou may also set `SRT_DATA_DIR` to control where auto-generated logs and cache files are placed.\n\n> **Path safety:** `SRT_DATA_DIR` and `--log-file` are validated at runtime to resolve within the user's home directory or system temp dir only. Paths that escape these boundaries (e.g. via `../`) are rejected.\n\n**`reserve retry` options:**\n| Option | Default | Description |\n|--------|---------|-------------|\n| `--train-id` | (all) | 1-based index from search; comma-separated for multiple |\n| `--timeout-minutes` | 60 | Total duration. Use 1440 for 24h |\n| `--wait-seconds` | 10 | Delay between attempts |\n| `--log-file` | auto | Explicit log file path (overrides `SRT_DATA_DIR` default) |\n\nLog markers to watch for:\n- `=== 시도 #N` — attempt number\n- `SUCCESS` — reservation succeeded (contains 예약번호, 좌석)\n- `TIMEOUT` — timed out without success\n\n### Step 3: Create periodic reporting cron job\nCreate an **isolated agentTurn** cron job (every 15 min) with **`--no-deliver`** (delivery mode: none).\nThe agent must use the `message` tool to post directly to the Discord channel — do **not** use `--announce` (the announce queue can fail with a gateway pairing error in isolated sessions).\n\nCLI:\n```bash\nopenclaw cron add \\\n  --agent srt \\\n  --name \"SRT 모니터링 보고 (15분마다)\" \\\n  --every 15m \\\n  --session isolated \\\n  --no-deliver \\\n  --message \"...\"\n```\n\nAgent message must instruct:\n1. Check process status:\n   ```bash\n   cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve status --pid-file <pid_file>\n   ```\n2. Read log tail: `tail -50 <log_file>`\n3. Summarise attempt count, last attempt time, success/failure\n4. **Send report via `message` tool** (`channel=discord`, `target=<channel_id>`)\n5. On `SUCCESS` in log → include 예약번호/좌석 in message, then remove this cron job and termination job\n6. On `NOT_RUNNING` without `SUCCESS` → report crash, remove this cron job\n\nThe message payload must include this job's own ID and the termination job ID so it can self-remove.\n\n### Step 4: Create termination job\nCreate an **isolated agentTurn** `at`-schedule cron job (`--no-deliver`, `--delete-after-run`) at the deadline.\n\nCLI:\n```bash\nopenclaw cron add \\\n  --agent srt \\\n  --name \"SRT 모니터링 종료\" \\\n  --at \"<ISO UTC time>\" \\\n  --session isolated \\\n  --no-deliver \\\n  --delete-after-run \\\n  --message \"...\"\n```\n\nAgent message must instruct:\n1. Stop the process:\n   ```bash\n   cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve stop --pid-file <pid_file>\n   ```\n2. Remove the reporting cron job by ID\n3. Read final log and **send outcome via `message` tool** to Discord channel\n\n---\n\n## JSON Output\n\n**Search result item:**\n```json\n{\n  \"train_number\": \"369\",\n  \"departure_time\": \"200000\",\n  \"arrival_time\": \"213600\",\n  \"departure_station\": \"수서\",\n  \"arrival_station\": \"동대구\",\n  \"seat_available\": false,\n  \"general_seat\": \"매진\",\n  \"special_seat\": \"매진\",\n  \"train_id\": \"1\"\n}\n```\n\n**Reservation result:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"train_number\": \"369\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\nExit codes: `0` = success · `1` = retryable (no seats) · `2` = fatal\n\n---\n\n## Error Handling\n\n| Error | Cause | Resolution |\n|-------|-------|-----------|\n| `AuthenticationFailed` | Wrong credentials | Check `SRT_PHONE` / `SRT_PASSWORD` |\n| `NoSeatsAvailable` | Sold out | Use `--retry` or try different train |\n| `StationNotFound` | Invalid name | Use Korean station names above |\n| `NoTrainsFound` | No trains found | Try different date/time |\n| `RateLimitExceeded` | Too many attempts | Wait a few minutes |\n\n---\n\n## Natural Language Handling\n\nExtract from Korean input:\n- Stations → Korean names (수서, 동대구, etc.)\n- Date → relative (\"내일\", \"다음주 금요일\") to YYYYMMDD\n- Time → (\"20시 이후\", \"오후 2시\") to HHMMSS\n- Passenger count → default 1 if not specified\n\n**Patterns:**\n- \"검색해줘\" → `train search`\n- \"예약해줘\" (one-shot) → `train search` then `reserve one-shot`\n- \"취소표 나오면 잡아줘 / 될 때까지 돌려줘\" → Continuous Monitoring flow above\n- \"내 예약 확인해줘\" → `reserve list`\n- \"취소해줘\" → `list` then `cancel`\n\n## Payment Note\nReservations must be paid via SRT app or <https://etk.srail.kr> within ~20 minutes of reservation.\n\nFile v1.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"1.1.1\",\n  \"publishedAt\": 1771687682899\n}\n\nFile v1.1.1:skill-card.md\n\n## Description:\n\nKorean SRT (Super Rapid Train) search, reservation, and booking management.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[khj809](https://clawhub.ai/user/khj809)\n\n### License/Terms of Use:\n\n\n## Use Case:\n\nExternal users and developers use this skill to search Korean SRT trains, make one-shot reservations, monitor for canceled seats, list reservations, and cancel reservations from an agent workflow.\n\n### Deployment Geography for Use:\n\nGlobal (service use is for Korean SRT routes).\n\n## Known Risks and Mitigations:\n\nRisk: The skill uses SRT account credentials and can make or cancel reservations under the user's account.\n\nMitigation: Run it only in a trusted environment, provide credentials through the documented environment variables, and review reservation or cancellation actions before execution.\n\nRisk: Continuous monitoring can create long-running background processes, cron jobs, logs, and Discord reports containing booking details.\n\nMitigation: Use monitoring only with an explicit timeout, known log and Discord destinations, and cleanup steps for reporting and termination jobs.\n\nRisk: Weak PID-file process control and an unpinned SRTrain dependency can affect process management and dependency trust.\n\nMitigation: Use only PID files created for the current run and prefer a pinned, reviewed SRTrain dependency version.\n\n## Reference(s):\n\n- [ClawHub SRT Skill Page](https://clawhub.ai/khj809/skills/srt)\n- [SRT Skill Homepage](https://github.com/khj809/openclaw-srt-skill)\n- [SRTrain PyPI Package](https://pypi.org/project/SRTrain)\n- [SRTrain GitHub Repository](https://github.com/ryanking13/SRT)\n- [SRT Booking Website](https://etk.srail.kr)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with shell command examples and JSON CLI output.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include reservation identifiers, seat details, payment-required status, process status, log summaries, and exit codes.]\n\n## Skill Version(s):\n\n1.1.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.1.0: 6 files, 16642 bytes\n\nFiles: scripts/reserve.py (15869b), scripts/srt_cli.py (7040b), scripts/train.py (5301b), scripts/utils.py (13731b), SKILL.md (6826b), _meta.json (122b)\n\nFile v1.1.0:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"], \"env\": [\"SRT_PHONE\", \"SRT_PASSWORD\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain from PyPI (uv) — source: https://pypi.org/project/SRTrain / https://github.com/ryanking13/SRT\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\n## Prerequisites\n\n- Environment variables `SRT_PHONE` (format: `010-XXXX-XXXX`) and `SRT_PASSWORD` must be set before running scripts.\n\n## Reference\n\n**Environment variables:**\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `SRT_PHONE` | ✅ | SRT account phone number (hyphens required: `010-XXXX-XXXX`) |\n| `SRT_PASSWORD` | ✅ | SRT account password |\n| `SRT_DATA_DIR` | optional | Directory for logs, cache, and state files. Defaults to system temp dir (`/tmp/srt`). |\n\n**Station names** (Korean only):\n수서, 부산, 동대구, 대전, 천안아산, 오송, 광주송정, 울산, 포항, 경주, 김천구미, 익산, 전주, 목포, 신경주\n\n**Date:** `YYYYMMDD` · **Time:** `HHMMSS` (e.g. `200000` = 20:00)\n\n---\n\n## Commands\n\n### Search Trains\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nSearch params and results are cached (in `SRT_DATA_DIR`) and required by `reserve`.\n\n### Reserve (one-shot)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve one-shot --train-id \"1\"\n```\n`--train-id` is the 1-based index from search results. Must run `train search` first.\n\n### View Reservations\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve list --format json\n```\n\n### Cancel Reservation\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve cancel \\\n  --reservation-id \"RES123456\" --confirm\n```\n\n---\n\n## Continuous Monitoring (취소표 모니터링)\n\nFor \"keep trying until a seat opens\" requests, **do not loop inside a cron job**.\nInstead: run `srt_cli.py reserve retry` as a persistent background process, then create a separate cron job to read the log and report.\n\n### Step 1: Search (populate cache)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nNote the `train_id` of the target train from the results.\n\n### Step 2: Start background retry process\n```bash\nLOG_FILE=<choose_any_path>.log\nPID_FILE=<choose_any_path>.pid\ncd <project_dir> && nohup uv run --with SRTrain python3 scripts/srt_cli.py reserve retry \\\n  --train-id <id> --timeout-minutes 1440 --wait-seconds 10 \\\n  --log-file \"$LOG_FILE\" > /dev/null 2>&1 &\necho $! > \"$PID_FILE\"\n```\n\nThe script prints `LOG_FILE: <path>` on startup — capture this to know exactly where logs are written.\nYou may also set `SRT_DATA_DIR` to control where auto-generated logs and cache files are placed.\n\n> **Path safety:** `SRT_DATA_DIR` and `--log-file` are validated at runtime to resolve within the user's home directory or system temp dir only. Paths that escape these boundaries (e.g. via `../`) are rejected.\n\n**`reserve retry` options:**\n| Option | Default | Description |\n|--------|---------|-------------|\n| `--train-id` | (all) | 1-based index from search; comma-separated for multiple |\n| `--timeout-minutes` | 60 | Total duration. Use 1440 for 24h |\n| `--wait-seconds` | 10 | Delay between attempts |\n| `--log-file` | auto | Explicit log file path (overrides `SRT_DATA_DIR` default) |\n\nLog markers to watch for:\n- `=== 시도 #N` — attempt number\n- `SUCCESS` — reservation succeeded (contains 예약번호, 좌석)\n- `TIMEOUT` — timed out without success\n\n### Step 3: Create periodic reporting cron job\nCreate an **isolated agentTurn** cron job (every 15 min) that:\n1. Checks process status:\n   ```bash\n   cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve status --pid-file <pid_file>\n   ```\n   Outputs `RUNNING (<pid>)` or `NOT_RUNNING (...)` — no shell command substitution involved.\n2. Reads log tail: `tail -50 <log_file>`\n3. Parses attempt count and last attempt time from log\n4. Reports to channel\n5. On `SUCCESS` in log → extract 예약번호/좌석 info, report, remove this cron job\n6. On `TIMEOUT` or process `NOT_RUNNING` → report, remove this cron job\n\nThe cron job's task message must include its own job ID (update after creation) so it can self-remove.\n\n### Step 4: Create termination job\nCreate an **isolated agentTurn** `at`-schedule cron job at the end time that:\n1. Stops the process:\n   ```bash\n   cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve stop --pid-file <pid_file>\n   ```\n2. Removes the reporting cron job by ID\n3. Reads final log and reports outcome\n\n---\n\n## JSON Output\n\n**Search result item:**\n```json\n{\n  \"train_number\": \"369\",\n  \"departure_time\": \"200000\",\n  \"arrival_time\": \"213600\",\n  \"departure_station\": \"수서\",\n  \"arrival_station\": \"동대구\",\n  \"seat_available\": false,\n  \"general_seat\": \"매진\",\n  \"special_seat\": \"매진\",\n  \"train_id\": \"1\"\n}\n```\n\n**Reservation result:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"train_number\": \"369\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\nExit codes: `0` = success · `1` = retryable (no seats) · `2` = fatal\n\n---\n\n## Error Handling\n\n| Error | Cause | Resolution |\n|-------|-------|-----------|\n| `AuthenticationFailed` | Wrong credentials | Check `SRT_PHONE` / `SRT_PASSWORD` |\n| `NoSeatsAvailable` | Sold out | Use `--retry` or try different train |\n| `StationNotFound` | Invalid name | Use Korean station names above |\n| `NoTrainsFound` | No trains found | Try different date/time |\n| `RateLimitExceeded` | Too many attempts | Wait a few minutes |\n\n---\n\n## Natural Language Handling\n\nExtract from Korean input:\n- Stations → Korean names (수서, 동대구, etc.)\n- Date → relative (\"내일\", \"다음주 금요일\") to YYYYMMDD\n- Time → (\"20시 이후\", \"오후 2시\") to HHMMSS\n- Passenger count → default 1 if not specified\n\n**Patterns:**\n- \"검색해줘\" → `train search`\n- \"예약해줘\" (one-shot) → `train search` then `reserve one-shot`\n- \"취소표 나오면 잡아줘 / 될 때까지 돌려줘\" → Continuous Monitoring flow above\n- \"내 예약 확인해줘\" → `reserve list`\n- \"취소해줘\" → `list` then `cancel`\n\n## Payment Note\nReservations must be paid via SRT app or <https://etk.srail.kr> within ~20 minutes of reservation.\n\nFile v1.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1771499278441\n}\n\nArchive v1.0.0: 9 files, 18984 bytes\n\nFiles: scripts/cancel_booking.py (3154b), scripts/check_retry_log.py (1895b), scripts/make_reservation.py (10895b), scripts/search_trains.py (3420b), scripts/srt_cli.py (4423b), scripts/utils.py (14126b), scripts/view_bookings.py (2848b), SKILL.md (6386b), _meta.json (122b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"], \"env\": [\"SRT_PHONE\", \"SRT_PASSWORD\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain from PyPI (uv) — source: https://pypi.org/project/SRTrain / https://github.com/ryanking13/SRT\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\n## Prerequisites\n\n- Environment variables `SRT_PHONE` (format: `010-XXXX-XXXX`) and `SRT_PASSWORD` must be set before running scripts.\n\n## Reference\n\n**Environment variables:**\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `SRT_PHONE` | ✅ | SRT account phone number (hyphens required: `010-XXXX-XXXX`) |\n| `SRT_PASSWORD` | ✅ | SRT account password |\n| `SRT_DATA_DIR` | optional | Directory for logs, cache, and state files. Defaults to system temp dir (`/tmp/srt`). |\n\n**Station names** (Korean only):\n수서, 부산, 동대구, 대전, 천안아산, 오송, 광주송정, 울산, 포항, 경주, 김천구미, 익산, 전주, 목포, 신경주\n\n**Date:** `YYYYMMDD` · **Time:** `HHMMSS` (e.g. `200000` = 20:00)\n\n---\n\n## Commands\n\n### Search\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nSearch params and results are cached (in `SRT_DATA_DIR`) and required by `reserve`.\n\n### Reserve (one-shot)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n```\n`--train-id` is the 1-based index from search results. Must run `search` first.\n\n### View Bookings\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py list --format json\n```\n\n### Cancel\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" --confirm\n```\n\n---\n\n## Continuous Monitoring (취소표 모니터링)\n\nFor \"keep trying until a seat opens\" requests, **do not loop inside a cron job**.\nInstead: run `make_reservation.py --retry` as a persistent background process, then create a separate cron job to read the log and report.\n\n### Step 1: Search (populate cache)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nNote the `train_id` of the target train from the results.\n\n### Step 2: Start background retry process\n```bash\nLOG_FILE=<choose_any_path>.log\nPID_FILE=<choose_any_path>.pid\ncd <project_dir> && nohup uv run --with SRTrain python3 scripts/make_reservation.py \\\n  --train-id <id> --retry --timeout-minutes 1440 --wait-seconds 10 \\\n  --log-file \"$LOG_FILE\" > /dev/null 2>&1 &\necho $! > \"$PID_FILE\"\n```\n\nThe script prints `LOG_FILE: <path>` on startup — capture this to know exactly where logs are written.\nYou may also set `SRT_DATA_DIR` to control where auto-generated logs and cache files are placed.\n\n**`make_reservation.py` options:**\n| Option | Default | Description |\n|--------|---------|-------------|\n| `--train-id` | (all) | 1-based index from search; comma-separated for multiple |\n| `--retry` | false | Enable continuous retry mode |\n| `--timeout-minutes` | 60 | Total duration. Use 1440 for 24h |\n| `--wait-seconds` | 10 | Delay between attempts |\n| `--log-file` | auto | Explicit log file path (overrides `SRT_DATA_DIR` default) |\n\nLog markers to watch for:\n- `=== 시도 #N` — attempt number\n- `SUCCESS` — reservation succeeded (contains 예약번호, 좌석)\n- `TIMEOUT` — timed out without success\n\n### Step 3: Create periodic reporting cron job\nCreate an **isolated agentTurn** cron job (every 15 min) that:\n1. Checks process status:\n   ```bash\n   PID=$(cat <pid_file> 2>/dev/null)\n   kill -0 \"$PID\" 2>/dev/null && echo \"RUNNING\" || echo \"NOT_RUNNING\"\n   ```\n2. Reads log tail: `tail -50 <log_file>`\n3. Parses attempt count and last attempt time from log\n4. Reports to channel\n5. On `SUCCESS` in log → extract 예약번호/좌석 info, report, remove this cron job\n6. On `TIMEOUT` or process `NOT_RUNNING` → report, remove this cron job\n\nThe cron job's task message must include its own job ID (update after creation) so it can self-remove.\n\n### Step 4: Create termination job\nCreate an **isolated agentTurn** `at`-schedule cron job at the end time that:\n1. Kills the process: `kill $(cat <pid_file>)`\n2. Removes the reporting cron job by ID\n3. Reads final log and reports outcome\n\n---\n\n## JSON Output\n\n**Search result item:**\n```json\n{\n  \"train_number\": \"369\",\n  \"departure_time\": \"200000\",\n  \"arrival_time\": \"213600\",\n  \"departure_station\": \"수서\",\n  \"arrival_station\": \"동대구\",\n  \"seat_available\": false,\n  \"general_seat\": \"매진\",\n  \"special_seat\": \"매진\",\n  \"train_id\": \"1\"\n}\n```\n\n**Reservation result:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"train_number\": \"369\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\nExit codes: `0` = success · `1` = retryable (no seats) · `2` = fatal\n\n---\n\n## Error Handling\n\n| Error | Cause | Resolution |\n|-------|-------|-----------|\n| `AuthenticationFailed` | Wrong credentials | Check `SRT_PHONE` / `SRT_PASSWORD` |\n| `NoSeatsAvailable` | Sold out | Use `--retry` or try different train |\n| `StationNotFound` | Invalid name | Use Korean station names above |\n| `NoTrainsFound` | No trains found | Try different date/time |\n| `RateLimitExceeded` | Too many attempts | Wait a few minutes |\n\n---\n\n## Natural Language Handling\n\nExtract from Korean input:\n- Stations → Korean names (수서, 동대구, etc.)\n- Date → relative (\"내일\", \"다음주 금요일\") to YYYYMMDD\n- Time → (\"20시 이후\", \"오후 2시\") to HHMMSS\n- Passenger count → default 1 if not specified\n\n**Patterns:**\n- \"검색해줘\" → `search`\n- \"예약해줘\" (one-shot) → `search` then `reserve`\n- \"취소표 나오면 잡아줘 / 될 때까지 돌려줘\" → Continuous Monitoring flow above\n- \"내 예약 확인해줘\" → `list`\n- \"취소해줘\" → `list` then `cancel`\n\n## Payment Note\nReservations must be paid via SRT app or <https://etk.srail.kr> within ~20 minutes of reservation.\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1771399593710\n}\n\nArchive v0.1.3: 9 files, 20675 bytes\n\nFiles: scripts/cancel_booking.py (3156b), scripts/check_retry_log.py (1507b), scripts/make_reservation.py (9163b), scripts/search_trains.py (3414b), scripts/srt_cli.py (4115b), scripts/utils.py (11340b), scripts/view_bookings.py (2848b), SKILL.md (16752b), _meta.json (122b)\n\nFile v0.1.3:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain (uv)\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\nOpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.\n\n## Features\n\n- 🔍 **Search trains** between stations with real-time seat availability\n- 🎫 **Make reservations** with automatic rate limiting to protect your account\n- 📋 **View bookings** to see all active reservations\n- 🗑️ **Cancel bookings** with confirmation prompts\n- 🤖 **AI-friendly** JSON output for programmatic access\n- 🛡️ **Rate limiting** to prevent account blocking (3s between reservations, 5s between searches)\n- ⚠️ **Retry protection** with maximum 10 attempts per session\n\n## Prerequisites\n\n1. **Python 3.10+** installed\n2. **SRT account** with phone number and password\n3. **OpenClaw** installed and configured\n\n## Configuration\n\nSet your SRT credentials as environment variables:\n\n```bash\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n```\n\nAdd these to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.) for persistence.\n\n**Security Note:** Avoid committing credentials to version control.\n\n**Important:** Phone number must include hyphens in the format `010-XXXX-XXXX`\n\n## Usage\n\n### User-Invocable Command\n\nUse the `/srt` slash command in OpenClaw:\n\n```\n/srt search --departure \"수서\" --arrival \"부산\" --date \"20260217\" --time \"140000\"\n/srt reserve --train-id \"1\"\n/srt reserve --retry --timeout-minutes 60\n/srt reserve --retry --train-id \"1,3,5\" --timeout-minutes 60\n/srt log -n 30\n/srt list\n/srt cancel --reservation-id \"RES123456\"\n```\n\n### Natural Language (AI-Orchestrated)\n\nThe AI can invoke this skill based on user intent:\n\n**Examples:**\n- \"2월 17일에 수서에서 부산 가는 기차 검색해줘\" *(Search trains)*\n- \"제일 빠른걸로 예약해줘\" *(Reserve first available)*\n- \"내 예약 확인해줘\" *(List bookings)*\n- \"부산 예약 취소해줘\" *(Cancel booking)*\n\n### Direct CLI Usage\n\n```bash\n# Search trains\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"140000\" \\\n  --passengers \"adult=2\"\n\n# Make reservation (single attempt)\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n\n# Make reservation with automatic retry - all trains (background mode recommended)\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \\\n  --timeout-minutes 60 \\\n  --wait-seconds 10\n\n# Make reservation with automatic retry - specific trains only\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \\\n  --train-id \"1,3,5\" \\\n  --timeout-minutes 60 \\\n  --wait-seconds 10\n\n# Check reservation log\nuv run --with SRTrain python3 scripts/srt_cli.py log -n 30\n\n# View bookings\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n\n# Cancel booking\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n## Common Korean Station Names\n\n**Main SRT Stations:**\n- 수서 (Suseo) - Seoul SRT station\n- 부산 (Busan)\n- 동대구 (Dongdaegu) - Daegu\n- 대전 (Daejeon)\n- 천안아산 (Cheonan-Asan)\n- 오송 (Osong)\n- 광주송정 (Gwangju-Songjeong)\n- 울산 (Ulsan)\n- 포항 (Pohang)\n- 경주 (Gyeongju)\n- 김천구미 (Gimcheon-Gumi)\n- 익산 (Iksan)\n- 전주 (Jeonju)\n- 목포 (Mokpo)\n- 신경주 (Singyeongju)\n\n**Important:** Station names MUST be in Korean (Hangul) for the SRT API to work correctly.\n\n## Date and Time Formats\n\n- **Date:** YYYYMMDD (e.g., `20260217` for February 17, 2026)\n- **Time:** HHMMSS (e.g., `140000` for 2:00 PM, `093000` for 9:30 AM)\n\n## Tools for AI Agent\n\nThis skill provides 5 tools for managing SRT train reservations:\n\n### 1. search_trains\nSearch for available trains between stations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"120000\"\n```\n\n**Returns:** JSON array of available trains with seat availability\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"train_id\": \"1\",\n      \"train_number\": \"301\",\n      \"train_name\": \"SRT301\",\n      \"departure_time\": \"120500\",\n      \"arrival_time\": \"143000\",\n      \"departure_station\": \"수서\",\n      \"arrival_station\": \"부산\",\n      \"seat_available\": true,\n      \"general_seat\": \"예약가능\",\n      \"special_seat\": \"예약가능\"\n    }\n  ]\n}\n```\n\n### 2. make_reservation\nReserve trains with optional automatic retry support.\n\n**Usage (single attempt):**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n```\n\n**Usage (with retry):**\n```bash\n# Try all trains\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \\\n  --timeout-minutes 60 \\\n  --wait-seconds 10\n\n# Try specific trains only\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --retry \\\n  --train-id \"1,3,5\" \\\n  --timeout-minutes 60 \\\n  --wait-seconds 10\n```\n\n**Options:**\n- `--train-id`: Specific train(s) to reserve (comma-separated, e.g., \"1\" or \"1,3,5\"; omit to try all trains)\n- `--retry`: Enable automatic retry on failure\n- `--timeout-minutes`: Maximum retry duration in minutes (default: 60)\n- `--wait-seconds`: Wait time between retry attempts in seconds (default: 10)\n\n**Behavior with --retry:**\n1. Cycles through all available trains from search results\n2. Waits `--wait-seconds` between attempts (plus rate-limiting delays)\n3. Continues until success or timeout\n4. Logs progress to `~/.openclaw/tmp/srt/reserve.log`\n\n**Returns:** Reservation details with payment deadline\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"journey_date\": \"20260217\",\n    \"journey_time\": \"120500\",\n    \"departure\": \"수서\",\n    \"arrival\": \"부산\",\n    \"train_number\": \"301\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true,\n    \"attempts\": 12\n  }\n}\n```\n\n**Note:** \n- Payment must be completed manually by user via SRT app/website\n- For retry mode, run in background with exec tool and periodically check logs\n\n### 3. view_bookings\nList all current reservations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n```\n\n**Returns:** JSON array of active reservations\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"reservation_id\": \"RES123456\",\n      \"journey_date\": \"20260217\",\n      \"journey_time\": \"120500\",\n      \"departure\": \"수서\",\n      \"arrival\": \"부산\",\n      \"train_number\": \"301\",\n      \"seat_number\": \"3A\",\n      \"payment_required\": true\n    }\n  ]\n}\n```\n\n### 4. cancel_booking\nCancel a reservation by ID.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n**Returns:** Cancellation confirmation\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"reservation_id\": \"RES123456\",\n    \"message\": \"Reservation cancelled successfully\"\n  }\n}\n```\n\n### 5. check_log\nCheck the progress of reservation attempts (especially useful for retry mode).\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py log -n 30\n```\n\n**Returns:** Last N lines of reservation log file (`~/.openclaw/tmp/srt/reserve.log`)\n\n**Options:**\n- `-n, --lines`: Number of lines to show (default: 20)\n\n**Log Format Example:**\n```\n[2026-02-03 11:00:00] INFO: === SRT 예약 시작 (재시도 모드) ===\n[2026-02-03 11:00:00] INFO: 타임아웃: 60분\n[2026-02-03 11:00:00] INFO: 재시도 간격: 10초\n[2026-02-03 11:00:00] INFO: 대상 열차: 1,3,5 (총 3개)\n[2026-02-03 11:00:05] INFO: === 시도 #1 (열차 1/3) ===\n[2026-02-03 11:00:05] INFO: 🎫 예약 시도 중... (열차 301, 120500)\n[2026-02-03 11:00:06] WARN: ❌ 좌석 없음 (열차 301)\n[2026-02-03 11:00:06] INFO: ⏳ 10초 대기 후 재시도...\n[2026-02-03 11:00:26] INFO: === 시도 #2 (열차 2/3) ===\n...\n[2026-02-03 11:05:00] SUCCESS: ✅ 예약 성공!\n```\n\n## Error Handling\n\nThe skill provides clear, actionable error messages:\n\n**Common Errors:**\n\n1. **AuthenticationFailed**\n   - Invalid credentials\n   - **Solution:** Check phone number and password in config\n\n2. **NoSeatsAvailable**\n   - Train is sold out\n   - **Solution:** Try next train or different time\n   - **Exit code:** 1 (retryable)\n\n3. **StationNotFound**\n   - Invalid station name\n   - **Solution:** Use Korean station names from the list above\n\n4. **NoTrainsFound**\n   - No trains for specified route/time\n   - **Solution:** Try different date or time\n\n5. **RateLimitExceeded**\n   - Too many retry attempts (max 10 per session)\n   - **Solution:** Wait a few minutes before trying again\n\n6. **NetworkError**\n   - Connection timeout or failure\n   - **Solution:** Check internet connection and retry\n\n**Exit Codes:**\n- `0` - Success\n- `1` - Retryable error (e.g., no seats available)\n- `2` - Fatal error (e.g., authentication failed, invalid input)\n\n## ⚠️ Rate Limiting and Account Protection\n\nTo protect your SRT account from being blocked by the server:\n\n- **Automatic delays** between requests:\n  - Minimum 3 seconds between reservation attempts\n  - Minimum 5 seconds between search requests\n- **Maximum 10 retry attempts** per session\n- **Exponential backoff** after failures (3s → 5s → 10s → 15s → 20s → 30s)\n\n**What this means for users:**\n- The skill will automatically wait between requests\n- You'll see waiting messages like \"⏳ SRT 서버 보호를 위해 대기 중 (3초)\"\n- If you hit the retry limit, wait a few minutes before trying again\n\n**For AI orchestration:**\n- The AI should inform users about delays during retries\n- Example: \"재시도 중입니다. 서버 보호를 위해 3초 대기합니다...\"\n- After 10 failed attempts, suggest alternatives like different times or dates\n\n## Natural Language Handling\n\nWhen users make requests in Korean, the AI should:\n\n1. **Extract parameters** from natural language:\n   - Stations (must convert to Korean if given in English)\n   - Date (relative dates like \"내일\", \"다음주 금요일\" → YYYYMMDD)\n   - Time (relative times like \"오후 2시\", \"12시 이후\" → HHMMSS)\n   - Passenger count (default to 1 if not specified)\n\n2. **Call tools in correct sequence:**\n   - Search before reserving\n   - List before canceling\n   - Handle retry logic with rate limiting\n\n3. **Handle errors gracefully:**\n   - If no seats available, try next train (with delays)\n   - If station not found, suggest correct Korean name\n   - Inform user about waiting times during rate limiting\n\n4. **Confirm actions in Korean:**\n   - \"예약이 완료되었습니다\" (Reservation completed)\n   - \"3초 후 다음 열차를 시도합니다\" (Trying next train in 3 seconds)\n   - \"결제는 SRT 앱에서 완료해주세요\" (Complete payment in SRT app)\n\n## Real-World Usage Scenarios\n\n### Scenario 1: Simple Reservation\n**User:** \"2월 17일에 수서에서 동대구 가는거 12시이후 제일 빠른걸로 2장 예약해줘\"\n\n**AI Actions:**\n1. Parse: departure=수서, arrival=동대구, date=20260217, time=120000, passengers=adult:2\n2. Search trains\n3. Select first available train\n4. Reserve train\n5. Confirm with payment reminder\n\n### Scenario 2: Retry Until Success\n**User:** \"매진이면 성공할때까지 반복해\"\n\n**AI Actions:**\n1. Search trains\n2. Start background retry:\n   ```bash\n   exec reserve --retry --timeout-minutes 60 --wait-seconds 10 (in background)\n   ```\n3. Create monitoring cron job (isolated session + agentTurn):\n   ```bash\n   cron add --job '{\n     \"schedule\": {\"kind\": \"every\", \"everyMs\": 120000},\n     \"payload\": {\n       \"kind\": \"agentTurn\",\n       \"message\": \"Check SRT retry log and report progress\",\n       \"deliver\": true,\n       \"channel\": \"discord\"\n     },\n     \"sessionTarget\": \"isolated\",\n     \"enabled\": true\n   }'\n   cron wake --mode \"now\"\n   ```\n4. Inform user: \"백그라운드 재시도 시작. 2분마다 업데이트합니다.\"\n\n## ⚠️ Background Retry Monitoring\n\n**MANDATORY:** Use isolated session + agentTurn cron jobs for monitoring `reserve --retry`.\n\n### Setup\n\n```bash\n# 1. Start background retry\nexec reserve --retry --timeout-minutes 60 (background)\n\n# 2. Create monitoring cron (isolated + agentTurn)\ncron add --job '{\n  \"schedule\": {\"kind\": \"every\", \"everyMs\": 120000},\n  \"payload\": {\n    \"kind\": \"agentTurn\",\n    \"message\": \"Check `srt_cli.py log -n 30`, parse progress, report to user. Delete cron if done.\",\n    \"deliver\": true,\n    \"channel\": \"discord\"\n  },\n  \"sessionTarget\": \"isolated\",\n  \"enabled\": true\n}'\n\n# 3. Wake immediately\ncron wake --mode \"now\"\n```\n\n### Requirements\n\n- **sessionTarget:** `\"isolated\"` (NOT \"main\")\n- **payload.kind:** `\"agentTurn\"` (NOT \"systemEvent\")\n- **payload.deliver:** `true`\n- **Schedule:** Every 1-3 minutes depending on task duration\n- **Wake:** Always call `cron wake --mode \"now\"` after creating job\n\n### Why\n\n- `systemEvent` in main session doesn't trigger agent action\n- `agentTurn` in isolated session actually executes and reports\n- Prevents blocking, message batching, and silent monitoring\n\n\n### Scenario 3: Check and Cancel\n**User:** \"내 예약 확인해주고 제일 빠른거 취소해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Parse JSON, find earliest by date/time\n3. Cancel reservation\n4. Confirm cancellation\n\n### Scenario 4: Modify Booking\n**User:** \"부산 예약 취소하고 동대구로 다시 예약해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Find Busan reservation\n3. Cancel Busan reservation\n4. Search for trains to 동대구 (same date/time)\n5. Reserve new train\n6. Confirm both actions\n\n## Payment Notes\n\n**IMPORTANT:** This skill can search and reserve trains, but **cannot process payments**.\n\nAfter making a reservation:\n1. You'll receive a reservation number\n2. Payment must be completed via:\n   - SRT mobile app (iOS/Android)\n   - SRT website (https://etk.srail.kr)\n3. Check payment deadline (usually 20 minutes after reservation)\n4. Unpaid reservations will be automatically cancelled\n\n## Troubleshooting\n\n### \"SRT 인증 정보를 찾을 수 없습니다\"\n- Verify `SRT_PHONE` and `SRT_PASSWORD` environment variables are set\n- Check your shell profile (`~/.zshrc`, `~/.bashrc`) has `export` keyword\n- Example: `export SRT_PHONE=\"010-1234-5678\"`\n\n### \"검색 결과를 찾을 수 없습니다\"\n- Run `search` command before `reserve`\n- Search results are cached in `~/.openclaw/tmp/srt/last_search.pkl`\n\n### \"재시도 한도 초과\"\n- You've made 10 reservation attempts\n- Wait 5-10 minutes before trying again\n- Try different trains or times\n\n### Login failures\n- Verify credentials are correct\n- Check if SRT service is available\n- Ensure phone number format includes hyphens (010-1234-5678)\n\n## Development\n\n### Testing Locally\n\n```bash\n# Install dependencies\n# Install uv if not already installed\n# https://docs.astral.sh/uv/getting-started/installation/\n\n# Configure credentials\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n\n# Test commands\nuv run --with SRTrain python3 scripts/srt_cli.py search --departure \"수서\" --arrival \"부산\" --date \"20260203\" --time \"140000\"\nuv run --with SRTrain python3 scripts/srt_cli.py list\n```\n\n### Publishing to ClawHub\n\n```bash\n# Authenticate\nclawhub login\n\n# Publish\nclawhub publish . \\\n  --slug srt \\\n  --name \"SRT Korean Train Service\" \\\n  --version 0.1.2 \\\n  --tags latest\n```\n\n## License\n\nMIT\n\n## Support\n\nFor issues or questions:\n- File an issue on GitHub\n- Check SRT service status: https://etk.srail.kr\n\n## Version History\n\n- **0.1.3** - Retry improvements and monitoring requirements\n  - Unified `reserve` command with `--retry` flag\n  - Added `--timeout-minutes` for time-based retry limits (default: 60)\n  - Added `--train-id` support for comma-separated multiple trains (e.g., \"1,3,5\")\n  - Changed `--wait-seconds` default from 20 to 10 seconds\n  - Search includes sold-out trains by default (`available_only=False`)\n  - **Monitoring:** Isolated session + agentTurn cron jobs required for background retry\n- **0.1.2** - Add `--all` flag for sold-out trains (deprecated)\n- **0.1.1** - Use `uv` for dependency management\n  - Replace venv/pip with `uv run --with SRTrain`\n  - Environment variables only for credentials (remove config file support)\n- **0.1.0** - Initial release\n  - Search trains\n  - Make reservations\n  - View bookings\n  - Cancel bookings\n  - Rate limiting protection\n  - AI-friendly JSON output\n\nFile v0.1.3:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"0.1.3\",\n  \"publishedAt\": 1770094955252\n}\n\nArchive v0.1.2: 8 files, 16337 bytes\n\nFiles: scripts/cancel_booking.py (3156b), scripts/make_reservation.py (3669b), scripts/search_trains.py (3547b), scripts/srt_cli.py (2968b), scripts/utils.py (11340b), scripts/view_bookings.py (2848b), SKILL.md (12203b), _meta.json (122b)\n\nFile v0.1.2:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain (uv)\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\nOpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.\n\n## Features\n\n- 🔍 **Search trains** between stations with real-time seat availability\n- 🎫 **Make reservations** with automatic rate limiting to protect your account\n- 📋 **View bookings** to see all active reservations\n- 🗑️ **Cancel bookings** with confirmation prompts\n- 🤖 **AI-friendly** JSON output for programmatic access\n- 🛡️ **Rate limiting** to prevent account blocking (3s between reservations, 5s between searches)\n- ⚠️ **Retry protection** with maximum 10 attempts per session\n\n## Prerequisites\n\n1. **Python 3.10+** installed\n2. **SRT account** with phone number and password\n3. **OpenClaw** installed and configured\n\n## Configuration\n\nSet your SRT credentials as environment variables:\n\n```bash\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n```\n\nAdd these to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.) for persistence.\n\n**Security Note:** Avoid committing credentials to version control.\n\n**Important:** Phone number must include hyphens in the format `010-XXXX-XXXX`\n\n## Usage\n\n### User-Invocable Command\n\nUse the `/srt` slash command in OpenClaw:\n\n```\n/srt search --departure \"수서\" --arrival \"부산\" --date \"20260217\" --time \"140000\"\n/srt reserve --train-id \"1\"\n/srt list\n/srt cancel --reservation-id \"RES123456\"\n```\n\n### Natural Language (AI-Orchestrated)\n\nThe AI can invoke this skill based on user intent:\n\n**Examples:**\n- \"2월 17일에 수서에서 부산 가는 기차 검색해줘\" *(Search trains)*\n- \"제일 빠른걸로 예약해줘\" *(Reserve first available)*\n- \"내 예약 확인해줘\" *(List bookings)*\n- \"부산 예약 취소해줘\" *(Cancel booking)*\n\n### Direct CLI Usage\n\n```bash\n# Search trains\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"140000\" \\\n  --passengers \"adult=2\"\n\n# Make reservation (uses train ID from search results)\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n\n# View bookings\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n\n# Cancel booking\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n## Common Korean Station Names\n\n**Main SRT Stations:**\n- 수서 (Suseo) - Seoul SRT station\n- 부산 (Busan)\n- 동대구 (Dongdaegu) - Daegu\n- 대전 (Daejeon)\n- 천안아산 (Cheonan-Asan)\n- 오송 (Osong)\n- 광주송정 (Gwangju-Songjeong)\n- 울산 (Ulsan)\n- 포항 (Pohang)\n- 경주 (Gyeongju)\n- 김천구미 (Gimcheon-Gumi)\n- 익산 (Iksan)\n- 전주 (Jeonju)\n- 목포 (Mokpo)\n- 신경주 (Singyeongju)\n\n**Important:** Station names MUST be in Korean (Hangul) for the SRT API to work correctly.\n\n## Date and Time Formats\n\n- **Date:** YYYYMMDD (e.g., `20260217` for February 17, 2026)\n- **Time:** HHMMSS (e.g., `140000` for 2:00 PM, `093000` for 9:30 AM)\n\n## Tools for AI Agent\n\nThis skill provides 4 tools for managing SRT train reservations:\n\n### 1. search_trains\nSearch for available trains between stations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"120000\"\n```\n\n**Returns:** JSON array of available trains with seat availability\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"train_id\": \"1\",\n      \"train_number\": \"301\",\n      \"train_name\": \"SRT301\",\n      \"departure_time\": \"120500\",\n      \"arrival_time\": \"143000\",\n      \"departure_station\": \"수서\",\n      \"arrival_station\": \"부산\",\n      \"seat_available\": true,\n      \"general_seat\": \"예약가능\",\n      \"special_seat\": \"예약가능\"\n    }\n  ]\n}\n```\n\n### 2. make_reservation\nReserve a specific train from search results.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n```\n\n**Returns:** Reservation details with payment deadline\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"journey_date\": \"20260217\",\n    \"journey_time\": \"120500\",\n    \"departure\": \"수서\",\n    \"arrival\": \"부산\",\n    \"train_number\": \"301\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\n**Note:** Payment must be completed manually by user via SRT app/website.\n\n### 3. view_bookings\nList all current reservations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n```\n\n**Returns:** JSON array of active reservations\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"reservation_id\": \"RES123456\",\n      \"journey_date\": \"20260217\",\n      \"journey_time\": \"120500\",\n      \"departure\": \"수서\",\n      \"arrival\": \"부산\",\n      \"train_number\": \"301\",\n      \"seat_number\": \"3A\",\n      \"payment_required\": true\n    }\n  ]\n}\n```\n\n### 4. cancel_booking\nCancel a reservation by ID.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n**Returns:** Cancellation confirmation\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"reservation_id\": \"RES123456\",\n    \"message\": \"Reservation cancelled successfully\"\n  }\n}\n```\n\n## Error Handling\n\nThe skill provides clear, actionable error messages:\n\n**Common Errors:**\n\n1. **AuthenticationFailed**\n   - Invalid credentials\n   - **Solution:** Check phone number and password in config\n\n2. **NoSeatsAvailable**\n   - Train is sold out\n   - **Solution:** Try next train or different time\n   - **Exit code:** 1 (retryable)\n\n3. **StationNotFound**\n   - Invalid station name\n   - **Solution:** Use Korean station names from the list above\n\n4. **NoTrainsFound**\n   - No trains for specified route/time\n   - **Solution:** Try different date or time\n\n5. **RateLimitExceeded**\n   - Too many retry attempts (max 10 per session)\n   - **Solution:** Wait a few minutes before trying again\n\n6. **NetworkError**\n   - Connection timeout or failure\n   - **Solution:** Check internet connection and retry\n\n**Exit Codes:**\n- `0` - Success\n- `1` - Retryable error (e.g., no seats available)\n- `2` - Fatal error (e.g., authentication failed, invalid input)\n\n## ⚠️ Rate Limiting and Account Protection\n\nTo protect your SRT account from being blocked by the server:\n\n- **Automatic delays** between requests:\n  - Minimum 3 seconds between reservation attempts\n  - Minimum 5 seconds between search requests\n- **Maximum 10 retry attempts** per session\n- **Exponential backoff** after failures (3s → 5s → 10s → 15s → 20s → 30s)\n\n**What this means for users:**\n- The skill will automatically wait between requests\n- You'll see waiting messages like \"⏳ SRT 서버 보호를 위해 대기 중 (3초)\"\n- If you hit the retry limit, wait a few minutes before trying again\n\n**For AI orchestration:**\n- The AI should inform users about delays during retries\n- Example: \"재시도 중입니다. 서버 보호를 위해 3초 대기합니다...\"\n- After 10 failed attempts, suggest alternatives like different times or dates\n\n## Natural Language Handling\n\nWhen users make requests in Korean, the AI should:\n\n1. **Extract parameters** from natural language:\n   - Stations (must convert to Korean if given in English)\n   - Date (relative dates like \"내일\", \"다음주 금요일\" → YYYYMMDD)\n   - Time (relative times like \"오후 2시\", \"12시 이후\" → HHMMSS)\n   - Passenger count (default to 1 if not specified)\n\n2. **Call tools in correct sequence:**\n   - Search before reserving\n   - List before canceling\n   - Handle retry logic with rate limiting\n\n3. **Handle errors gracefully:**\n   - If no seats available, try next train (with delays)\n   - If station not found, suggest correct Korean name\n   - Inform user about waiting times during rate limiting\n\n4. **Confirm actions in Korean:**\n   - \"예약이 완료되었습니다\" (Reservation completed)\n   - \"3초 후 다음 열차를 시도합니다\" (Trying next train in 3 seconds)\n   - \"결제는 SRT 앱에서 완료해주세요\" (Complete payment in SRT app)\n\n## Real-World Usage Scenarios\n\n### Scenario 1: Simple Reservation\n**User:** \"2월 17일에 수서에서 동대구 가는거 12시이후 제일 빠른걸로 2장 예약해줘\"\n\n**AI Actions:**\n1. Parse: departure=수서, arrival=동대구, date=20260217, time=120000, passengers=adult:2\n2. Search trains\n3. Select first available train\n4. Reserve train\n5. Confirm with payment reminder\n\n### Scenario 2: Retry Until Success\n**User:** \"매진이면 성공할때까지 반복해\"\n\n**AI Actions:**\n1. Search trains\n2. Loop through available trains:\n   - Try to reserve\n   - If sold out, wait 3-5 seconds (rate limiting)\n   - Try next train\n   - Max 10 attempts\n3. Report success or exhaustion\n\n### Scenario 3: Check and Cancel\n**User:** \"내 예약 확인해주고 제일 빠른거 취소해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Parse JSON, find earliest by date/time\n3. Cancel reservation\n4. Confirm cancellation\n\n### Scenario 4: Modify Booking\n**User:** \"부산 예약 취소하고 동대구로 다시 예약해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Find Busan reservation\n3. Cancel Busan reservation\n4. Search for trains to 동대구 (same date/time)\n5. Reserve new train\n6. Confirm both actions\n\n## Payment Notes\n\n**IMPORTANT:** This skill can search and reserve trains, but **cannot process payments**.\n\nAfter making a reservation:\n1. You'll receive a reservation number\n2. Payment must be completed via:\n   - SRT mobile app (iOS/Android)\n   - SRT website (https://etk.srail.kr)\n3. Check payment deadline (usually 20 minutes after reservation)\n4. Unpaid reservations will be automatically cancelled\n\n## Troubleshooting\n\n### \"SRT 인증 정보를 찾을 수 없습니다\"\n- Verify `SRT_PHONE` and `SRT_PASSWORD` environment variables are set\n- Check your shell profile (`~/.zshrc`, `~/.bashrc`) has `export` keyword\n- Example: `export SRT_PHONE=\"010-1234-5678\"`\n\n### \"검색 결과를 찾을 수 없습니다\"\n- Run `search` command before `reserve`\n- Search results are cached in `~/.openclaw/tmp/srt/last_search.pkl`\n\n### \"재시도 한도 초과\"\n- You've made 10 reservation attempts\n- Wait 5-10 minutes before trying again\n- Try different trains or times\n\n### Login failures\n- Verify credentials are correct\n- Check if SRT service is available\n- Ensure phone number format includes hyphens (010-1234-5678)\n\n## Development\n\n### Testing Locally\n\n```bash\n# Install dependencies\n# Install uv if not already installed\n# https://docs.astral.sh/uv/getting-started/installation/\n\n# Configure credentials\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n\n# Test commands\nuv run --with SRTrain python3 scripts/srt_cli.py search --departure \"수서\" --arrival \"부산\" --date \"20260203\" --time \"140000\"\nuv run --with SRTrain python3 scripts/srt_cli.py list\n```\n\n### Publishing to ClawHub\n\n```bash\n# Authenticate\nclawhub login\n\n# Publish\nclawhub publish . \\\n  --slug srt \\\n  --name \"SRT Korean Train Service\" \\\n  --version 0.1.2 \\\n  --tags latest\n```\n\n## License\n\nMIT\n\n## Support\n\nFor issues or questions:\n- File an issue on GitHub\n- Check SRT service status: https://etk.srail.kr\n\n## Version History\n\n- **0.1.2** - Add `--all` flag for sold-out trains\n  - Search now supports `--all` to include sold-out trains (passes `available_only=False`)\n- **0.1.1** - Use `uv` for dependency management\n  - Replace venv/pip with `uv run --with SRTrain`\n  - Environment variables only for credentials (remove config file support)\n- **0.1.0** - Initial release\n  - Search trains\n  - Make reservations\n  - View bookings\n  - Cancel bookings\n  - Rate limiting protection\n  - AI-friendly JSON output\n\nFile v0.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"0.1.2\",\n  \"publishedAt\": 1770024302645\n}\n\nArchive v0.1.1: 8 files, 16096 bytes\n\nFiles: scripts/cancel_booking.py (3156b), scripts/make_reservation.py (3669b), scripts/search_trains.py (3358b), scripts/srt_cli.py (2864b), scripts/utils.py (11340b), scripts/view_bookings.py (2848b), SKILL.md (11886b), _meta.json (122b)\n\nFile v0.1.1:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain (uv)\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\nOpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.\n\n## Features\n\n- 🔍 **Search trains** between stations with real-time seat availability\n- 🎫 **Make reservations** with automatic rate limiting to protect your account\n- 📋 **View bookings** to see all active reservations\n- 🗑️ **Cancel bookings** with confirmation prompts\n- 🤖 **AI-friendly** JSON output for programmatic access\n- 🛡️ **Rate limiting** to prevent account blocking (3s between reservations, 5s between searches)\n- ⚠️ **Retry protection** with maximum 10 attempts per session\n\n## Prerequisites\n\n1. **Python 3.10+** installed\n2. **SRT account** with phone number and password\n3. **OpenClaw** installed and configured\n\n## Configuration\n\nSet your SRT credentials as environment variables:\n\n```bash\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n```\n\nAdd these to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.) for persistence.\n\n**Security Note:** Avoid committing credentials to version control.\n\n**Important:** Phone number must include hyphens in the format `010-XXXX-XXXX`\n\n## Usage\n\n### User-Invocable Command\n\nUse the `/srt` slash command in OpenClaw:\n\n```\n/srt search --departure \"수서\" --arrival \"부산\" --date \"20260217\" --time \"140000\"\n/srt reserve --train-id \"1\"\n/srt list\n/srt cancel --reservation-id \"RES123456\"\n```\n\n### Natural Language (AI-Orchestrated)\n\nThe AI can invoke this skill based on user intent:\n\n**Examples:**\n- \"2월 17일에 수서에서 부산 가는 기차 검색해줘\" *(Search trains)*\n- \"제일 빠른걸로 예약해줘\" *(Reserve first available)*\n- \"내 예약 확인해줘\" *(List bookings)*\n- \"부산 예약 취소해줘\" *(Cancel booking)*\n\n### Direct CLI Usage\n\n```bash\n# Search trains\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"140000\" \\\n  --passengers \"adult=2\"\n\n# Make reservation (uses train ID from search results)\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n\n# View bookings\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n\n# Cancel booking\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n## Common Korean Station Names\n\n**Main SRT Stations:**\n- 수서 (Suseo) - Seoul SRT station\n- 부산 (Busan)\n- 동대구 (Dongdaegu) - Daegu\n- 대전 (Daejeon)\n- 천안아산 (Cheonan-Asan)\n- 오송 (Osong)\n- 광주송정 (Gwangju-Songjeong)\n- 울산 (Ulsan)\n- 포항 (Pohang)\n- 경주 (Gyeongju)\n- 김천구미 (Gimcheon-Gumi)\n- 익산 (Iksan)\n- 전주 (Jeonju)\n- 목포 (Mokpo)\n- 신경주 (Singyeongju)\n\n**Important:** Station names MUST be in Korean (Hangul) for the SRT API to work correctly.\n\n## Date and Time Formats\n\n- **Date:** YYYYMMDD (e.g., `20260217` for February 17, 2026)\n- **Time:** HHMMSS (e.g., `140000` for 2:00 PM, `093000` for 9:30 AM)\n\n## Tools for AI Agent\n\nThis skill provides 4 tools for managing SRT train reservations:\n\n### 1. search_trains\nSearch for available trains between stations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"120000\"\n```\n\n**Returns:** JSON array of available trains with seat availability\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"train_id\": \"1\",\n      \"train_number\": \"301\",\n      \"train_name\": \"SRT301\",\n      \"departure_time\": \"120500\",\n      \"arrival_time\": \"143000\",\n      \"departure_station\": \"수서\",\n      \"arrival_station\": \"부산\",\n      \"seat_available\": true,\n      \"general_seat\": \"예약가능\",\n      \"special_seat\": \"예약가능\"\n    }\n  ]\n}\n```\n\n### 2. make_reservation\nReserve a specific train from search results.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py reserve --train-id \"1\"\n```\n\n**Returns:** Reservation details with payment deadline\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"journey_date\": \"20260217\",\n    \"journey_time\": \"120500\",\n    \"departure\": \"수서\",\n    \"arrival\": \"부산\",\n    \"train_number\": \"301\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\n**Note:** Payment must be completed manually by user via SRT app/website.\n\n### 3. view_bookings\nList all current reservations.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py list --format json\n```\n\n**Returns:** JSON array of active reservations\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"reservation_id\": \"RES123456\",\n      \"journey_date\": \"20260217\",\n      \"journey_time\": \"120500\",\n      \"departure\": \"수서\",\n      \"arrival\": \"부산\",\n      \"train_number\": \"301\",\n      \"seat_number\": \"3A\",\n      \"payment_required\": true\n    }\n  ]\n}\n```\n\n### 4. cancel_booking\nCancel a reservation by ID.\n\n**Usage:**\n```bash\nuv run --with SRTrain python3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n**Returns:** Cancellation confirmation\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"reservation_id\": \"RES123456\",\n    \"message\": \"Reservation cancelled successfully\"\n  }\n}\n```\n\n## Error Handling\n\nThe skill provides clear, actionable error messages:\n\n**Common Errors:**\n\n1. **AuthenticationFailed**\n   - Invalid credentials\n   - **Solution:** Check phone number and password in config\n\n2. **NoSeatsAvailable**\n   - Train is sold out\n   - **Solution:** Try next train or different time\n   - **Exit code:** 1 (retryable)\n\n3. **StationNotFound**\n   - Invalid station name\n   - **Solution:** Use Korean station names from the list above\n\n4. **NoTrainsFound**\n   - No trains for specified route/time\n   - **Solution:** Try different date or time\n\n5. **RateLimitExceeded**\n   - Too many retry attempts (max 10 per session)\n   - **Solution:** Wait a few minutes before trying again\n\n6. **NetworkError**\n   - Connection timeout or failure\n   - **Solution:** Check internet connection and retry\n\n**Exit Codes:**\n- `0` - Success\n- `1` - Retryable error (e.g., no seats available)\n- `2` - Fatal error (e.g., authentication failed, invalid input)\n\n## ⚠️ Rate Limiting and Account Protection\n\nTo protect your SRT account from being blocked by the server:\n\n- **Automatic delays** between requests:\n  - Minimum 3 seconds between reservation attempts\n  - Minimum 5 seconds between search requests\n- **Maximum 10 retry attempts** per session\n- **Exponential backoff** after failures (3s → 5s → 10s → 15s → 20s → 30s)\n\n**What this means for users:**\n- The skill will automatically wait between requests\n- You'll see waiting messages like \"⏳ SRT 서버 보호를 위해 대기 중 (3초)\"\n- If you hit the retry limit, wait a few minutes before trying again\n\n**For AI orchestration:**\n- The AI should inform users about delays during retries\n- Example: \"재시도 중입니다. 서버 보호를 위해 3초 대기합니다...\"\n- After 10 failed attempts, suggest alternatives like different times or dates\n\n## Natural Language Handling\n\nWhen users make requests in Korean, the AI should:\n\n1. **Extract parameters** from natural language:\n   - Stations (must convert to Korean if given in English)\n   - Date (relative dates like \"내일\", \"다음주 금요일\" → YYYYMMDD)\n   - Time (relative times like \"오후 2시\", \"12시 이후\" → HHMMSS)\n   - Passenger count (default to 1 if not specified)\n\n2. **Call tools in correct sequence:**\n   - Search before reserving\n   - List before canceling\n   - Handle retry logic with rate limiting\n\n3. **Handle errors gracefully:**\n   - If no seats available, try next train (with delays)\n   - If station not found, suggest correct Korean name\n   - Inform user about waiting times during rate limiting\n\n4. **Confirm actions in Korean:**\n   - \"예약이 완료되었습니다\" (Reservation completed)\n   - \"3초 후 다음 열차를 시도합니다\" (Trying next train in 3 seconds)\n   - \"결제는 SRT 앱에서 완료해주세요\" (Complete payment in SRT app)\n\n## Real-World Usage Scenarios\n\n### Scenario 1: Simple Reservation\n**User:** \"2월 17일에 수서에서 동대구 가는거 12시이후 제일 빠른걸로 2장 예약해줘\"\n\n**AI Actions:**\n1. Parse: departure=수서, arrival=동대구, date=20260217, time=120000, passengers=adult:2\n2. Search trains\n3. Select first available train\n4. Reserve train\n5. Confirm with payment reminder\n\n### Scenario 2: Retry Until Success\n**User:** \"매진이면 성공할때까지 반복해\"\n\n**AI Actions:**\n1. Search trains\n2. Loop through available trains:\n   - Try to reserve\n   - If sold out, wait 3-5 seconds (rate limiting)\n   - Try next train\n   - Max 10 attempts\n3. Report success or exhaustion\n\n### Scenario 3: Check and Cancel\n**User:** \"내 예약 확인해주고 제일 빠른거 취소해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Parse JSON, find earliest by date/time\n3. Cancel reservation\n4. Confirm cancellation\n\n### Scenario 4: Modify Booking\n**User:** \"부산 예약 취소하고 동대구로 다시 예약해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Find Busan reservation\n3. Cancel Busan reservation\n4. Search for trains to 동대구 (same date/time)\n5. Reserve new train\n6. Confirm both actions\n\n## Payment Notes\n\n**IMPORTANT:** This skill can search and reserve trains, but **cannot process payments**.\n\nAfter making a reservation:\n1. You'll receive a reservation number\n2. Payment must be completed via:\n   - SRT mobile app (iOS/Android)\n   - SRT website (https://etk.srail.kr)\n3. Check payment deadline (usually 20 minutes after reservation)\n4. Unpaid reservations will be automatically cancelled\n\n## Troubleshooting\n\n### \"SRT 인증 정보를 찾을 수 없습니다\"\n- Verify `SRT_PHONE` and `SRT_PASSWORD` environment variables are set\n- Check your shell profile (`~/.zshrc`, `~/.bashrc`) has `export` keyword\n- Example: `export SRT_PHONE=\"010-1234-5678\"`\n\n### \"검색 결과를 찾을 수 없습니다\"\n- Run `search` command before `reserve`\n- Search results are cached in `~/.openclaw/tmp/srt/last_search.pkl`\n\n### \"재시도 한도 초과\"\n- You've made 10 reservation attempts\n- Wait 5-10 minutes before trying again\n- Try different trains or times\n\n### Login failures\n- Verify credentials are correct\n- Check if SRT service is available\n- Ensure phone number format includes hyphens (010-1234-5678)\n\n## Development\n\n### Testing Locally\n\n```bash\n# Install dependencies\n# Install uv if not already installed\n# https://docs.astral.sh/uv/getting-started/installation/\n\n# Configure credentials\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n\n# Test commands\nuv run --with SRTrain python3 scripts/srt_cli.py search --departure \"수서\" --arrival \"부산\" --date \"20260203\" --time \"140000\"\nuv run --with SRTrain python3 scripts/srt_cli.py list\n```\n\n### Publishing to ClawHub\n\n```bash\n# Authenticate\nclawhub login\n\n# Publish\nclawhub publish . \\\n  --slug srt \\\n  --name \"SRT Korean Train Service\" \\\n  --version 1.0.0 \\\n  --tags latest\n```\n\n## License\n\nMIT\n\n## Support\n\nFor issues or questions:\n- File an issue on GitHub\n- Check SRT service status: https://etk.srail.kr\n\n## Version History\n\n- **1.0.0** - Initial release\n  - Search trains\n  - Make reservations\n  - View bookings\n  - Cancel bookings\n  - Rate limiting protection\n  - AI-friendly JSON output\n\nFile v0.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"0.1.1\",\n  \"publishedAt\": 1770020375985\n}\n\nArchive v0.1.0: 8 files, 16077 bytes\n\nFiles: scripts/cancel_booking.py (3156b), scripts/make_reservation.py (3669b), scripts/search_trains.py (3358b), scripts/srt_cli.py (2864b), scripts/utils.py (11340b), scripts/view_bookings.py (2848b), SKILL.md (11648b), _meta.json (122b)\n\nFile v0.1.0:SKILL.md\n\n---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain (uv)\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\nOpenClaw skill for managing Korean SRT (Super Rapid Train) reservations with search, booking, view, and cancellation capabilities.\n\n## Features\n\n- 🔍 **Search trains** between stations with real-time seat availability\n- 🎫 **Make reservations** with automatic rate limiting to protect your account\n- 📋 **View bookings** to see all active reservations\n- 🗑️ **Cancel bookings** with confirmation prompts\n- 🤖 **AI-friendly** JSON output for programmatic access\n- 🛡️ **Rate limiting** to prevent account blocking (3s between reservations, 5s between searches)\n- ⚠️ **Retry protection** with maximum 10 attempts per session\n\n## Prerequisites\n\n1. **Python 3.10+** installed\n2. **SRT account** with phone number and password\n3. **OpenClaw** installed and configured\n\n## Configuration\n\nSet your SRT credentials as environment variables:\n\n```bash\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n```\n\nAdd these to your shell profile (`~/.zshrc`, `~/.bashrc`, etc.) for persistence.\n\n**Security Note:** Avoid committing credentials to version control.\n\n**Important:** Phone number must include hyphens in the format `010-XXXX-XXXX`\n\n## Usage\n\n### User-Invocable Command\n\nUse the `/srt` slash command in OpenClaw:\n\n```\n/srt search --departure \"수서\" --arrival \"부산\" --date \"20260217\" --time \"140000\"\n/srt reserve --train-id \"1\"\n/srt list\n/srt cancel --reservation-id \"RES123456\"\n```\n\n### Natural Language (AI-Orchestrated)\n\nThe AI can invoke this skill based on user intent:\n\n**Examples:**\n- \"2월 17일에 수서에서 부산 가는 기차 검색해줘\" *(Search trains)*\n- \"제일 빠른걸로 예약해줘\" *(Reserve first available)*\n- \"내 예약 확인해줘\" *(List bookings)*\n- \"부산 예약 취소해줘\" *(Cancel booking)*\n\n### Direct CLI Usage\n\n```bash\n# Search trains\npython3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"140000\" \\\n  --passengers \"adult=2\"\n\n# Make reservation (uses train ID from search results)\npython3 scripts/srt_cli.py reserve --train-id \"1\"\n\n# View bookings\npython3 scripts/srt_cli.py list --format json\n\n# Cancel booking\npython3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n## Common Korean Station Names\n\n**Main SRT Stations:**\n- 수서 (Suseo) - Seoul SRT station\n- 부산 (Busan)\n- 동대구 (Dongdaegu) - Daegu\n- 대전 (Daejeon)\n- 천안아산 (Cheonan-Asan)\n- 오송 (Osong)\n- 광주송정 (Gwangju-Songjeong)\n- 울산 (Ulsan)\n- 포항 (Pohang)\n- 경주 (Gyeongju)\n- 김천구미 (Gimcheon-Gumi)\n- 익산 (Iksan)\n- 전주 (Jeonju)\n- 목포 (Mokpo)\n- 신경주 (Singyeongju)\n\n**Important:** Station names MUST be in Korean (Hangul) for the SRT API to work correctly.\n\n## Date and Time Formats\n\n- **Date:** YYYYMMDD (e.g., `20260217` for February 17, 2026)\n- **Time:** HHMMSS (e.g., `140000` for 2:00 PM, `093000` for 9:30 AM)\n\n## Tools for AI Agent\n\nThis skill provides 4 tools for managing SRT train reservations:\n\n### 1. search_trains\nSearch for available trains between stations.\n\n**Usage:**\n```bash\npython3 scripts/srt_cli.py search \\\n  --departure \"수서\" \\\n  --arrival \"부산\" \\\n  --date \"20260217\" \\\n  --time \"120000\"\n```\n\n**Returns:** JSON array of available trains with seat availability\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"train_id\": \"1\",\n      \"train_number\": \"301\",\n      \"train_name\": \"SRT301\",\n      \"departure_time\": \"120500\",\n      \"arrival_time\": \"143000\",\n      \"departure_station\": \"수서\",\n      \"arrival_station\": \"부산\",\n      \"seat_available\": true,\n      \"general_seat\": \"예약가능\",\n      \"special_seat\": \"예약가능\"\n    }\n  ]\n}\n```\n\n### 2. make_reservation\nReserve a specific train from search results.\n\n**Usage:**\n```bash\npython3 scripts/srt_cli.py reserve --train-id \"1\"\n```\n\n**Returns:** Reservation details with payment deadline\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"reservation_id\": \"RES123456\",\n    \"journey_date\": \"20260217\",\n    \"journey_time\": \"120500\",\n    \"departure\": \"수서\",\n    \"arrival\": \"부산\",\n    \"train_number\": \"301\",\n    \"seat_number\": \"3A\",\n    \"payment_required\": true\n  }\n}\n```\n\n**Note:** Payment must be completed manually by user via SRT app/website.\n\n### 3. view_bookings\nList all current reservations.\n\n**Usage:**\n```bash\npython3 scripts/srt_cli.py list --format json\n```\n\n**Returns:** JSON array of active reservations\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"reservation_id\": \"RES123456\",\n      \"journey_date\": \"20260217\",\n      \"journey_time\": \"120500\",\n      \"departure\": \"수서\",\n      \"arrival\": \"부산\",\n      \"train_number\": \"301\",\n      \"seat_number\": \"3A\",\n      \"payment_required\": true\n    }\n  ]\n}\n```\n\n### 4. cancel_booking\nCancel a reservation by ID.\n\n**Usage:**\n```bash\npython3 scripts/srt_cli.py cancel \\\n  --reservation-id \"RES123456\" \\\n  --confirm\n```\n\n**Returns:** Cancellation confirmation\n\n**JSON Format:**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"success\": true,\n    \"reservation_id\": \"RES123456\",\n    \"message\": \"Reservation cancelled successfully\"\n  }\n}\n```\n\n## Error Handling\n\nThe skill provides clear, actionable error messages:\n\n**Common Errors:**\n\n1. **AuthenticationFailed**\n   - Invalid credentials\n   - **Solution:** Check phone number and password in config\n\n2. **NoSeatsAvailable**\n   - Train is sold out\n   - **Solution:** Try next train or different time\n   - **Exit code:** 1 (retryable)\n\n3. **StationNotFound**\n   - Invalid station name\n   - **Solution:** Use Korean station names from the list above\n\n4. **NoTrainsFound**\n   - No trains for specified route/time\n   - **Solution:** Try different date or time\n\n5. **RateLimitExceeded**\n   - Too many retry attempts (max 10 per session)\n   - **Solution:** Wait a few minutes before trying again\n\n6. **NetworkError**\n   - Connection timeout or failure\n   - **Solution:** Check internet connection and retry\n\n**Exit Codes:**\n- `0` - Success\n- `1` - Retryable error (e.g., no seats available)\n- `2` - Fatal error (e.g., authentication failed, invalid input)\n\n## ⚠️ Rate Limiting and Account Protection\n\nTo protect your SRT account from being blocked by the server:\n\n- **Automatic delays** between requests:\n  - Minimum 3 seconds between reservation attempts\n  - Minimum 5 seconds between search requests\n- **Maximum 10 retry attempts** per session\n- **Exponential backoff** after failures (3s → 5s → 10s → 15s → 20s → 30s)\n\n**What this means for users:**\n- The skill will automatically wait between requests\n- You'll see waiting messages like \"⏳ SRT 서버 보호를 위해 대기 중 (3초)\"\n- If you hit the retry limit, wait a few minutes before trying again\n\n**For AI orchestration:**\n- The AI should inform users about delays during retries\n- Example: \"재시도 중입니다. 서버 보호를 위해 3초 대기합니다...\"\n- After 10 failed attempts, suggest alternatives like different times or dates\n\n## Natural Language Handling\n\nWhen users make requests in Korean, the AI should:\n\n1. **Extract parameters** from natural language:\n   - Stations (must convert to Korean if given in English)\n   - Date (relative dates like \"내일\", \"다음주 금요일\" → YYYYMMDD)\n   - Time (relative times like \"오후 2시\", \"12시 이후\" → HHMMSS)\n   - Passenger count (default to 1 if not specified)\n\n2. **Call tools in correct sequence:**\n   - Search before reserving\n   - List before canceling\n   - Handle retry logic with rate limiting\n\n3. **Handle errors gracefully:**\n   - If no seats available, try next train (with delays)\n   - If station not found, suggest correct Korean name\n   - Inform user about waiting times during rate limiting\n\n4. **Confirm actions in Korean:**\n   - \"예약이 완료되었습니다\" (Reservation completed)\n   - \"3초 후 다음 열차를 시도합니다\" (Trying next train in 3 seconds)\n   - \"결제는 SRT 앱에서 완료해주세요\" (Complete payment in SRT app)\n\n## Real-World Usage Scenarios\n\n### Scenario 1: Simple Reservation\n**User:** \"2월 17일에 수서에서 동대구 가는거 12시이후 제일 빠른걸로 2장 예약해줘\"\n\n**AI Actions:**\n1. Parse: departure=수서, arrival=동대구, date=20260217, time=120000, passengers=adult:2\n2. Search trains\n3. Select first available train\n4. Reserve train\n5. Confirm with payment reminder\n\n### Scenario 2: Retry Until Success\n**User:** \"매진이면 성공할때까지 반복해\"\n\n**AI Actions:**\n1. Search trains\n2. Loop through available trains:\n   - Try to reserve\n   - If sold out, wait 3-5 seconds (rate limiting)\n   - Try next train\n   - Max 10 attempts\n3. Report success or exhaustion\n\n### Scenario 3: Check and Cancel\n**User:** \"내 예약 확인해주고 제일 빠른거 취소해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Parse JSON, find earliest by date/time\n3. Cancel reservation\n4. Confirm cancellation\n\n### Scenario 4: Modify Booking\n**User:** \"부산 예약 취소하고 동대구로 다시 예약해줘\"\n\n**AI Actions:**\n1. List reservations\n2. Find Busan reservation\n3. Cancel Busan reservation\n4. Search for trains to 동대구 (same date/time)\n5. Reserve new train\n6. Confirm both actions\n\n## Payment Notes\n\n**IMPORTANT:** This skill can search and reserve trains, but **cannot process payments**.\n\nAfter making a reservation:\n1. You'll receive a reservation number\n2. Payment must be completed via:\n   - SRT mobile app (iOS/Android)\n   - SRT website (https://etk.srail.kr)\n3. Check payment deadline (usually 20 minutes after reservation)\n4. Unpaid reservations will be automatically cancelled\n\n## Troubleshooting\n\n### \"SRT 인증 정보를 찾을 수 없습니다\"\n- Verify `SRT_PHONE` and `SRT_PASSWORD` environment variables are set\n- Check your shell profile (`~/.zshrc`, `~/.bashrc`) has `export` keyword\n- Example: `export SRT_PHONE=\"010-1234-5678\"`\n\n### \"검색 결과를 찾을 수 없습니다\"\n- Run `search` command before `reserve`\n- Search results are cached in `~/.openclaw/tmp/srt/last_search.pkl`\n\n### \"재시도 한도 초과\"\n- You've made 10 reservation attempts\n- Wait 5-10 minutes before trying again\n- Try different trains or times\n\n### Login failures\n- Verify credentials are correct\n- Check if SRT service is available\n- Ensure phone number format includes hyphens (010-1234-5678)\n\n## Development\n\n### Testing Locally\n\n```bash\n# Install dependencies\npython3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n\n# Configure credentials\nexport SRT_PHONE=\"010-1234-5678\"\nexport SRT_PASSWORD=\"your_password\"\n\n# Test commands\npython3 scripts/srt_cli.py search --departure \"수서\" --arrival \"부산\" --date \"20260203\" --time \"140000\"\npython3 scripts/srt_cli.py list\n```\n\n### Publishing to ClawHub\n\n```bash\n# Authenticate\nclawhub login\n\n# Publish\nclawhub publish . \\\n  --slug srt \\\n  --name \"SRT Korean Train Service\" \\\n  --version 1.0.0 \\\n  --tags latest\n```\n\n## License\n\nMIT\n\n## Support\n\nFor issues or questions:\n- File an issue on GitHub\n- Check SRT service status: https://etk.srail.kr\n\n## Version History\n\n- **1.0.0** - Initial release\n  - Search trains\n  - Make reservations\n  - View bookings\n  - Cancel bookings\n  - Rate limiting protection\n  - AI-friendly JSON output\n\nFile v0.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1770019946620\n}","readmeExcerpt":"Skill: SRT Owner: khj809 Summary: Korean SRT (Super Rapid Train) search, reservation, and booking management Tags: latest:1.1.1 Version history: v1.1.1 | 2026-02-21T15:28:02.899Z | user Fix cron delivery for isolated sessions - Replace --announce delivery with --no-deliver + explicit message tool call - Avoids gateway closed (1008): pairing required error in isolated cron sessions - Update SKILL.md Step 3/4 with CLI-","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\""},{"language":"bash","snippet":"cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve one-shot --train-id \"1\""},{"language":"bash","snippet":"cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve list --format json"},{"language":"bash","snippet":"cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve cancel \\\n  --reservation-id \"RES123456\" --confirm"},{"language":"bash","snippet":"cd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\""},{"language":"bash","snippet":"LOG_FILE=<choose_any_path>.log\nPID_FILE=<choose_any_path>.pid\ncd <project_dir> && nohup uv run --with SRTrain python3 scripts/srt_cli.py reserve retry \\\n  --train-id <id> --timeout-minutes 1440 --wait-seconds 10 \\\n  --log-file \"$LOG_FILE\" > /dev/null 2>&1 &\necho $! > \"$PID_FILE\""}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: srt\ndescription: Korean SRT (Super Rapid Train) search, reservation, and booking management\nhomepage: https://github.com/khj809/openclaw-srt-skill\nuser-invocable: true\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🚅\",\n        \"requires\": { \"bins\": [\"python3\", \"uv\"], \"env\": [\"SRT_PHONE\", \"SRT_PASSWORD\"] },\n        \"install\": [\n          {\"id\": \"uv\", \"kind\": \"uv\", \"package\": \"SRTrain\", \"label\": \"Install SRTrain from PyPI (uv) — source: https://pypi.org/project/SRTrain / https://github.com/ryanking13/SRT\"}\n        ]\n      },\n  }\n---\n\n# SRT Korean Train Service Skill\n\n## Prerequisites\n\n- Environment variables `SRT_PHONE` (format: `010-XXXX-XXXX`) and `SRT_PASSWORD` must be set before running scripts.\n\n## Reference\n\n**Environment variables:**\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `SRT_PHONE` | ✅ | SRT account phone number (hyphens required: `010-XXXX-XXXX`) |\n| `SRT_PASSWORD` | ✅ | SRT account password |\n| `SRT_DATA_DIR` | optional | Directory for logs, cache, and state files. Defaults to system temp dir (`/tmp/srt`). |\n\n**Station names** (Korean only):\n수서, 부산, 동대구, 대전, 천안아산, 오송, 광주송정, 울산, 포항, 경주, 김천구미, 익산, 전주, 목포, 신경주\n\n**Date:** `YYYYMMDD` · **Time:** `HHMMSS` (e.g. `200000` = 20:00)\n\n---\n\n## Commands\n\n### Search Trains\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nSearch params and results are cached (in `SRT_DATA_DIR`) and required by `reserve`.\n\n### Reserve (one-shot)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve one-shot --train-id \"1\"\n```\n`--train-id` is the 1-based index from search results. Must run `train search` first.\n\n### View Reservations\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve list --format json\n```\n\n### Cancel Reservation\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py reserve cancel \\\n  --reservation-id \"RES123456\" --confirm\n```\n\n---\n\n## Continuous Monitoring (취소표 모니터링)\n\nFor \"keep trying until a seat opens\" requests, **do not loop inside a cron job**.\nInstead: run `srt_cli.py reserve retry` as a persistent background process, then create a separate cron job to read the log and report.\n\n### Step 1: Search (populate cache)\n```bash\ncd <project_dir> && uv run --with SRTrain python3 scripts/srt_cli.py train search \\\n  --departure \"수서\" --arrival \"동대구\" --date \"20260227\" --time \"200000\"\n```\nNote the `train_id` of the target train from the results.\n\n### Step 2: Start background retry process\n```bash\nLOG_FILE=<choose_any_path>.log\nPID_FILE=<choose_any_path>.pid\ncd <project_dir> && nohup uv run --with SRTrain python3 scripts/srt_cli.py reserve retry \\\n  --train-id <id> --timeout-minutes 1440 --wait-seconds 10 \\\n  --log-file \"$LOG_FILE\" > /dev/null 2>&1 &\necho $! > \"$PID_FILE\"\n```\n\nThe script prints `LOG_FILE: <path>` on startup — capture this to know exactly "},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7ddhdw57dav7g6yj7b0pytg580bmw2\",\n  \"slug\": \"srt\",\n  \"version\": \"1.1.1\",\n  \"publishedAt\": 1771687682899\n}"},{"path":"skill-card.md","content":"## Description:\n\nKorean SRT (Super Rapid Train) search, reservation, and booking management.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[khj809](https://clawhub.ai/user/khj809)\n\n### License/Terms of Use:\n\n\n## Use Case:\n\nExternal users and developers use this skill to search Korean SRT trains, make one-shot reservations, monitor for canceled seats, list reservations, and cancel reservations from an agent workflow.\n\n### Deployment Geography for Use:\n\nGlobal (service use is for Korean SRT routes).\n\n## Known Risks and Mitigations:\n\nRisk: The skill uses SRT account credentials and can make or cancel reservations under the user's account.\n\nMitigation: Run it only in a trusted environment, provide credentials through the documented environment variables, and review reservation or cancellation actions before execution.\n\nRisk: Continuous monitoring can create long-running background processes, cron jobs, logs, and Discord reports containing booking details.\n\nMitigation: Use monitoring only with an explicit timeout, known log and Discord destinations, and cleanup steps for reporting and termination jobs.\n\nRisk: Weak PID-file process control and an unpinned SRTrain dependency can affect process management and dependency trust.\n\nMitigation: Use only PID files created for the current run and prefer a pinned, reviewed SRTrain dependency version.\n\n## Reference(s):\n\n- [ClawHub SRT Skill Page](https://clawhub.ai/khj809/skills/srt)\n- [SRT Skill Homepage](https://github.com/khj809/openclaw-srt-skill)\n- [SRTrain PyPI Package](https://pypi.org/project/SRTrain)\n- [SRTrain GitHub Repository](https://github.com/ryanking13/SRT)\n- [SRT Booking Website](https://etk.srail.kr)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with shell command examples and JSON CLI output.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include reservation identifiers, seat details, payment-required status, process status, log summaries, and exit codes.]\n\n## Skill Version(s):\n\n1.1.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Korean SRT (Super Rapid Train) search, reservation, and booking management Skill: SRT Owner: khj809 Summary: Korean SRT (Super Rapid Train) search, reservation, and booking management Tags: latest:1.1.1 Version history: v1.1.1 | 2026-02-21T15:28:02.899Z | user Fix cron delivery for isolated sessions - Replace --announce delivery with --no-deliver + explicit message tool call - Avoids gateway closed (1008): pairing required error in isolated cron sessions - Update SKILL.md Step 3/4 with CLI-","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1328,"uniquenessScore":49,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T18:16:04.338Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:37:56.149Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}