{"id":"95240400-a4b2-4f8d-be5d-e92bc7e8009e","entityType":"agent","slug":"clawhub-openlittlebear-12306-android-adb","name":"12306 Android Adb","canonicalUrl":"https://www.xpersona.co/agent/clawhub-openlittlebear-12306-android-adb","canonicalPath":"/agent/clawhub-openlittlebear-12306-android-adb","generatedAt":"2026-10-11T10:51:18.444Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T07:07:25.836Z","emptyReason":null},"description":"12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us... Skill: 12306 Android Adb Owner: openlittlebear Summary: 12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us... Tags: 12306:1.0.0, android:1.0.0, booking:1.0.0, latest:2.2.2, train:1.0.0 Version history: v2.2.2 | 2026-08-30T08:31:54.865Z | user skillSpector cleanup: removed unproven raw-shell patterns (adb input t","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s176q9th3gerh5cagvwz73f4r187fgya:12306-android-adb","sourceUrl":"https://clawhub.ai/openlittlebear/12306-android-adb","homepage":"https://clawhub.ai/openlittlebear/skills/12306-android-adb","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/openlittlebear/12306-android-adb","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/openlittlebear/skills/12306-android-adb","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T07:07:25.836Z","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-11T07:07:25.836Z","emptyReason":null},"stars":null,"forks":null,"downloads":1127,"packageName":null,"latestVersion":"2.2.2","tractionLabel":"1.1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T07:07:25.824Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T07:07:25.836Z","lastCrawledAt":"2026-10-11T07:07:25.824Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T07:07:25.824Z","lastVerifiedAt":null,"highlights":[{"version":"2.2.2","createdAt":"2026-08-30T08:31:54.865Z","changelog":"skillSpector cleanup: removed unproven raw-shell patterns (adb input tap, cmd clipboard set, keyevent 279, ADBKeyboard broadcast, motionevent, monkey launch, am force-stop); text input now uiautomator2-only.","fileCount":4,"zipByteSize":10451},{"version":"2.2.1","createdAt":"2026-08-30T08:12:55.562Z","changelog":"Add Safety & Consent section (confirm before submitting, payment always manual, private screenshot storage).","fileCount":5,"zipByteSize":20783},{"version":"2.2.0","createdAt":"2026-08-30T05:22:37.936Z","changelog":"Add departure-station filter tactic (一车多站 breaks time order; tap station chip before scrolling) and 车票信息已过期(M0013) recovery: 确定→back→re-query→re-apply filter→re-book. Second successful booking (D203 上海松江→杭州南).","fileCount":5,"zipByteSize":20684},{"version":"2.1.0","createdAt":"2026-08-30T04:16:59.712Z","changelog":"Rewrite booking flow from a successful end-to-end booking (G3314 上海→苏州, 2026-08-30): new card-expand UI with per-row 预订 buttons, OCR-based navigation, scroll unsticking, clipboard Chinese input, Appium blocked on Realme.","fileCount":5,"zipByteSize":19420},{"version":"1.0.1","createdAt":"2026-05-31T23:53:21.128Z","changelog":"Minor update: Documentation files cleaned up, binary cache added. - Removed README.md and skill-card.md documentation files. - Added a compiled Python cache file (__pycache__/adb_helper.cpython-312.pyc). - No changes to core skill logic or functionality.","fileCount":4,"zipByteSize":9007},{"version":"1.0.0","createdAt":"2026-05-26T14:59:28.926Z","changelog":"12306-specific train ticket booking skill for Android via Appium bridge. - Provides end-to-end 12306 booking flow: UI structure, search, booking, and payment process. - Enforces use of appium-android-adb bridge for all interactions (never use raw ADB). - Explains app page detection, element IDs, and unique behaviors of 12306 (station search logic, booking steps). - Highlights pitfalls and manual steps such as fingerprint authentication. - Includes troubleshooting and UI element lookup guidance for reliable automation.","fileCount":5,"zipByteSize":8794}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s176q9th3gerh5cagvwz73f4r187fgya:12306-android-adb","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-openlittlebear-12306-android-adb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/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-11T10:51:18.442Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-12306-android-adb/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-11T07:07:25.836Z","emptyReason":null},"readme":"Skill: 12306 Android Adb\n\nOwner: openlittlebear\n\nSummary: 12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us...\n\nTags: 12306:1.0.0, android:1.0.0, booking:1.0.0, latest:2.2.2, train:1.0.0\n\nVersion history:\n\nv2.2.2 | 2026-08-30T08:31:54.865Z | user\n\nskillSpector cleanup: removed unproven raw-shell patterns (adb input tap, cmd clipboard set, keyevent 279, ADBKeyboard broadcast, motionevent, monkey launch, am force-stop); text input now uiautomator2-only.\n\nv2.2.1 | 2026-08-30T08:12:55.562Z | user\n\nAdd Safety & Consent section (confirm before submitting, payment always manual, private screenshot storage).\n\nv2.2.0 | 2026-08-30T05:22:37.936Z | user\n\nAdd departure-station filter tactic (一车多站 breaks time order; tap station chip before scrolling) and 车票信息已过期(M0013) recovery: 确定→back→re-query→re-apply filter→re-book. Second successful booking (D203 上海松江→杭州南).\n\nv2.1.0 | 2026-08-30T04:16:59.712Z | user\n\nRewrite booking flow from a successful end-to-end booking (G3314 上海→苏州, 2026-08-30): new card-expand UI with per-row 预订 buttons, OCR-based navigation, scroll unsticking, clipboard Chinese input, Appium blocked on Realme.\n\nv1.0.1 | 2026-05-31T23:53:21.128Z | user\n\nMinor update: Documentation files cleaned up, binary cache added.\n\n- Removed README.md and skill-card.md documentation files.\n- Added a compiled Python cache file (__pycache__/adb_helper.cpython-312.pyc).\n- No changes to core skill logic or functionality.\n\nv1.0.0 | 2026-05-26T14:59:28.926Z | auto\n\n12306-specific train ticket booking skill for Android via Appium bridge.\n\n- Provides end-to-end 12306 booking flow: UI structure, search, booking, and payment process.\n- Enforces use of appium-android-adb bridge for all interactions (never use raw ADB).\n- Explains app page detection, element IDs, and unique behaviors of 12306 (station search logic, booking steps).\n- Highlights pitfalls and manual steps such as fingerprint authentication.\n- Includes troubleshooting and UI element lookup guidance for reliable automation.\n\nArchive index:\n\nArchive v2.2.2: 4 files, 10451 bytes\n\nFiles: _meta.json (136b), adb_helper.py (10268b), skill-card.md (2145b), SKILL.md (11440b)\n\nFile v2.2.2:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: Book train tickets on the 12306 Android app via USB ADB. Battle-tested 2026-08-30 (two successful bookings: G3314 上海→苏州 and D203 上海松江→杭州南). Primary method: direct uiautomator2 + RapidOCR via ocr_bridge.py (see appium-android-adb skill). Covers the UC WebView virtual-list traps, the card-expand UI, departure-station filter (一车多站 time disorder), scroll-unsticking, clipboard Chinese input, and 车票信息已过期 (M0013) recovery.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app (com.MobileTicket) uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges. This doc reflects **two successful end-to-end bookings** on the current app version (2026-08-30, Realme RMX3350 1080x2400).\n\n## 🚨 Setup (proven)\n\n```bash\n# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n**Do NOT use the Appium bridge for 12306 on consumer phones** — Realme etc. block WRITE_SECURE_SETTINGS, so Appium settings/IME fail and the session never starts. Direct uiautomator2 + OCR works (atx-agent needs no special permission). All interaction goes through the OCR loop: `ocr_bridge.py` in the appium-android-adb skill — screenshot → RapidOCR → click/swipe → re-OCR verify.\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView:\n\n- Accessibility tree / DOM is mostly **collapsed** (all non-current items share y≈407 or y≈2255, h=6px) and intermittently renders. Never depend on it.\n- **OCR is the dependable eye**: RapidOCR reads Chinese out of the box (no tesseract language packs needed).\n- Raw `adb shell input tap` is **filtered** by the WebView. `d.click(x, y)` (uiautomator2) reliably delivers touches.\n- The list **skips sections** when scrolling: a departure-time window (e.g. 06:32) can be jumped over repeatedly.\n\n## New-App UI: Card Expansion + Per-Row 预订 (2026-08 version)\n\n**Collapsed train cards have NO 预订 button.** The flow is:\n\n1. Tap the **seat row** of a card (e.g. \"二等\" label area) → the card **expands** in place, showing seat rows: 二等 / 一等 / 商务 / 无座, each with price (e.g. `二等 ¥41 9折`).\n2. Each expanded row has its own **预订 button on the right edge** (on 1080px width: x≈898–980, h≈48, at the row's y).\n3. Tap that row's 预订 → 确认订单 page.\n\n```bash\n# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订\n```\n\n(Example coordinates from the real run: card row at (141, 2026) expanded; 二等 row 预订 at (939, 1987); order page followed.)\n\n## ⚠️ Departure-Station Filter — Do This BEFORE Scrolling (一车多站)\n\n**Without the filter, the list mixes departures from multiple stations and time order breaks.** A train that stops at several departure stations (一车多站, e.g. G7357) appears once per stop-time, all grouped adjacently — so you see 08:10 / 08:35 / 08:52 for the same train number and can't scan by time. Hit this in production (thought \"no 08:16 train exists\" — there was one).\n\n**Fix: tap the departure-station filter chip at the top of the list first** (chips row, y≈669-708 on 1080x2400; e.g. 上海松江 / 杭州南 / 上海虹桥 / 上海南):\n\n```python\nchip = [x for x in t if '松江' in x[0] and x[2] < 600]   # OCR: station name near top\nd.click((chip[0][1]+chip[0][3])//2, (chip[0][2]+chip[0][4])//2)\n```\n\nAfter filtering: one row per train, sorted by departure time, target times are findable by simple scrolling.\n\n**⚠️ The filter resets after every re-query** (查询车票) — re-apply the chip each time.\n\n## Booking Flow (proven end-to-end)\n\n### Step 0: Install & Login (only if app missing)\n\n- Download the official APK from the 12306 site (kyfw.12306.cn 下载页), e.g. `curl` the direct link → `adb install -r app.apk`\n- The user must log in manually (SMS/face) — automation cannot do this step.\n\n### Step 1: Home Page — Stations & Date\n\nStations: tap the station field → search box opens. **Chinese input via clipboard** (IME switching is blocked):\n\n```bash\n$PY ocr_bridge.py type 苏州 --x 400 --y 330   # set_clipboard + long-press field\n$PY ocr_bridge.py dump                        # find 粘贴 in OCR\n$PY ocr_bridge.py tap-text 粘贴               # paste → results appear\n$PY ocr_bridge.py tap-text 苏州站              # pick the main station\n```\n\nDate: the date picker opens with day cells — OCR the month grid and tap the day cell (e.g. tomorrow's cell right of 今天).\n\n### Step 2: Query & Navigate the Train List\n\nTap 查询车票. The list loads with earliest departures first.\n\n```bash\n$PY ocr_bridge.py deps        # HH:MM markers at x<250 = which time window is visible\n$PY ocr_bridge.py swipe up --scale 0.35     # normal forward scroll (≈2 cards)\n```\n\n- Track position with `deps` — you always know where you are, DOM or not.\n- **Apply the departure-station filter chip FIRST** (see section above) — without it the list is not time-ordered.\n- **Filter further if available**: tap 只看高铁/动车 (or 只看高铁) to shorten the list.\n- **List keeps skipping the target section**: `$PY ocr_bridge.py jump --n 3` (3 rapid scale-0.5 swipes breaks the stuck point), then micro-swipes back: `swipe up --scale 0.25`, `micro down`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`.\n- Trains to your destination: match OCR train numbers with regex `^[GDCK]\\d+` plus the destination name in the row text (ignore trains to other destinations, e.g. 太仓 when heading to 苏州).\n\n### Step 3: Expand Card & Tap the Row's 预订\n\n- Tap the target card's seat-row label (二等) to expand → verify expansion by OCR (prices ￥41 etc. appear).\n- Tap the expanded row's 预订 on the right edge.\n- If a quiet-carriage dialog appears (静音车厢 rules) → tap its confirm button (选择/继续).\n\n### Step 4: Select Passenger\n\n- On the 确认订单 page, verify train info + price via OCR markers.\n- Tap 选择乘车人 → passenger list appears → `tap-text <name>` (e.g. 熊天放).\n- Verify selection: OCR shows 已选 next to the name.\n- Tap 确认 / 完成 (bottom button).\n\n### Step 5: Submit Order & Verify\n\n```bash\n$PY ocr_bridge.py tap-text 提交订单\n$PY ocr_bridge.py wait-text 订单处理中      # order processing\n$PY ocr_bridge.py markers                   # look for 快速支付 / 立即支付\n```\n\n- `订单处理中` → wait and re-OCR (can take ~20-60s).\n- `快速支付` or `立即支付` + countdown at top = **order locked, success**. Report: train, date, route, seat, price, passenger, seat number, countdown.\n- **Payment is manual**: the user pays in Alipay/WeChat on the phone (指纹/密码 can't be automated). Typical lock window ≈19 minutes.\n\n### 车票信息已过期 (M0013) — Recovery\n\nIf the list data sat too long before submitting, the order page throws **\"车票信息已过期(M0013)\"**. Detect it by polling markers after 提交订单:\n\n```python\nfor i in range(8):\n    time.sleep(4)\n    markers = [x[0] for x in shot() if any(k in x[0] for k in\n               ('立即支付','快速支付','订单处理','温馨提示','取消订单','已过期','确定'))]\n    if any('已过期' in m or '确定' in m for m in markers): break   # ERROR\n    if any('立即支付' in m for m in markers): break                # SUCCESS\n```\n\nRecovery (proven):\n\n1. Tap **确定** on the dialog.\n2. `d.press('back')` ×2 → home page. (Pull-to-refresh on the list did NOT refresh the data — don't bother.)\n3. Tap **查询车票** for a full re-query → fresh list.\n4. **Re-apply the departure-station filter chip** (it resets on re-query).\n5. Scroll to the train → expand → 预订 → passenger → 提交订单. Fresh data submits without the error.\n\n## Scroll Tactics Cheat Sheet\n\n| Situation | Command |\n|-----------|---------|\n| Normal advance | `swipe up --scale 0.35` |\n| Fine-tune position | `micro up` / `micro down` (scale 0.15) |\n| Precise pixel scroll | `d.swipe(540, 1900, 540, 800, duration=0.4)` |\n| List stuck / skips target window | `jump --n 3`, then micro back |\n| Back up a little | `swipe down --scale 0.3` |\n\n## Decision Tree\n\n```\nOCR markers:\n  ├─ 查询车票                    → HOME — set stations/date → tap 查询车票\n  ├─ 提交订单 / 选择乘车人        → ORDER PAGE — passenger → 提交订单\n  ├─ 订单处理中                  → wait, re-OCR\n  ├─ 车票信息已过期 / 确定对话框  → EXPIRED — 确定 → back → 查询车票 → re-filter → re-book\n  ├─ 快速支付 / 立即支付          → SUCCESS — tell user to pay\n  ├─ deps() times + train numbers → TRAIN LIST — scroll/find → expand → 预订\n  ├─ 粘贴 menu visible           → after clipboard type, tap 粘贴\n  └─ unknown                     → dump full OCR and re-orient\n```\n\n## 🛡️ Safety & Consent\n\n- Use only when the user explicitly asks to book a ticket — never speculatively.\n- **Confirm before submitting**: show the user the train, date, route, seat,\n  price and passenger, and wait for confirmation before tapping 提交订单.\n- Payment (立即支付, Alipay/WeChat, password/fingerprint) is ALWAYS done by the\n  user on the phone — never automated.\n- Screenshots may contain personal data; they are stored in a private 0700 dir\n  (`~/.cache/ocr-bridge`) — see appium-android-adb for cleanup.\n\n## Common Pitfalls (all hit in production)\n\n1. **Never trust the DOM** — it collapses and lies. OCR every time.\n2. **Raw ADB taps are filtered** by UC WebView — always `d.click`.\n3. **Appium is dead on Realme** (WRITE_SECURE_SETTINGS blocked) — don't waste time on it.\n4. **IME switching blocked** — Chinese input = `set_clipboard` + long-press 粘贴.\n5. **The list skips departure windows** — `jump` past the stuck point, then micro-scroll.\n6. **Clicking 二等 toggles the card** — if it collapsed again, re-expand and click the row's right-edge 预订, not the label.\n7. **Screen auto-lock** — `adb shell svc power stayon true`.\n8. **一车多站 mixes the time order** — same train number appears at multiple departure times (one per 发站), grouped adjacently. Always apply the departure-station filter chip before scanning for a time.\n9. **Stale list → 车票信息已过期(M0013)** — list data expires while you sit on it. Recovery: 确定 → back → full re-query → **re-apply station filter** → re-book. Pull-to-refresh does NOT refresh the data.\n10. **The station filter resets on re-query** — re-apply the chip every time after 查询车票.\n11. **OCR misreads** — filter by region (x/y bounds), re-shoot after animations (sleep 2-3s).\n12. **Train numbers**: OCR gives `G3314` (no spaces); DOM gives `G 3 3 1 4`. Regex on OCR text.\n13. **USB/ADB can drop mid-session** — app state (filter + scroll position) survives; ask the user to replug, then continue where you left off.\n\nFile v2.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"2.2.2\",\n  \"publishedAt\": 1788078714865\n}\n\nFile v2.2.2:skill-card.md\n\n## Description:\n\nGuides agents through booking train tickets in the 12306 Android app over USB ADB using uiautomator2 and OCR-based verification.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgents assisting a user who explicitly asks to book a 12306 train ticket can use this skill to navigate the Android app, select trains and passengers, recover from stale ticket data, and stop before payment for user action.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill gives an agent broad ADB control over a phone already logged into 12306.\n\nMitigation: Use it only after an explicit user request, keep the confirmation step before submitting an order, and leave payment to the user on the phone.\n\nRisk: Screenshots, UI dumps, clipboard contents, and passenger details may expose sensitive data.\n\nMitigation: Avoid untrusted station or passenger text, clear the clipboard and temporary screenshot/UI files after use, and keep temporary storage private.\n\nRisk: Under-scoped helper behavior or unpinned dependencies can mishandle device commands or screen data.\n\nMitigation: Review commands before execution and pin dependencies during setup.\n\n## Reference(s):\n\n- [12306 Android Adb on ClawHub](https://clawhub.ai/openlittlebear/skills/12306-android-adb)\n- [openlittlebear publisher profile](https://clawhub.ai/user/openlittlebear)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, code, configuration]\n\n**Output Format:** [Markdown with inline bash and Python code blocks]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Directs agent behavior for Android ADB and OCR workflows; payment remains manual.]\n\n## Skill Version(s):\n\n2.2.2 (source: server release evidence)\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 v2.2.1: 5 files, 20783 bytes\n\nFiles: __pycache__/adb_helper.cpython-314.pyc (21785b), _meta.json (136b), adb_helper.py (12244b), skill-card.md (2201b), SKILL.md (11440b)\n\nFile v2.2.1:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: Book train tickets on the 12306 Android app via USB ADB. Battle-tested 2026-08-30 (two successful bookings: G3314 上海→苏州 and D203 上海松江→杭州南). Primary method: direct uiautomator2 + RapidOCR via ocr_bridge.py (see appium-android-adb skill). Covers the UC WebView virtual-list traps, the card-expand UI, departure-station filter (一车多站 time disorder), scroll-unsticking, clipboard Chinese input, and 车票信息已过期 (M0013) recovery.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app (com.MobileTicket) uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges. This doc reflects **two successful end-to-end bookings** on the current app version (2026-08-30, Realme RMX3350 1080x2400).\n\n## 🚨 Setup (proven)\n\n```bash\n# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n**Do NOT use the Appium bridge for 12306 on consumer phones** — Realme etc. block WRITE_SECURE_SETTINGS, so Appium settings/IME fail and the session never starts. Direct uiautomator2 + OCR works (atx-agent needs no special permission). All interaction goes through the OCR loop: `ocr_bridge.py` in the appium-android-adb skill — screenshot → RapidOCR → click/swipe → re-OCR verify.\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView:\n\n- Accessibility tree / DOM is mostly **collapsed** (all non-current items share y≈407 or y≈2255, h=6px) and intermittently renders. Never depend on it.\n- **OCR is the dependable eye**: RapidOCR reads Chinese out of the box (no tesseract language packs needed).\n- Raw `adb shell input tap` is **filtered** by the WebView. `d.click(x, y)` (uiautomator2) reliably delivers touches.\n- The list **skips sections** when scrolling: a departure-time window (e.g. 06:32) can be jumped over repeatedly.\n\n## New-App UI: Card Expansion + Per-Row 预订 (2026-08 version)\n\n**Collapsed train cards have NO 预订 button.** The flow is:\n\n1. Tap the **seat row** of a card (e.g. \"二等\" label area) → the card **expands** in place, showing seat rows: 二等 / 一等 / 商务 / 无座, each with price (e.g. `二等 ¥41 9折`).\n2. Each expanded row has its own **预订 button on the right edge** (on 1080px width: x≈898–980, h≈48, at the row's y).\n3. Tap that row's 预订 → 确认订单 page.\n\n```bash\n# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订\n```\n\n(Example coordinates from the real run: card row at (141, 2026) expanded; 二等 row 预订 at (939, 1987); order page followed.)\n\n## ⚠️ Departure-Station Filter — Do This BEFORE Scrolling (一车多站)\n\n**Without the filter, the list mixes departures from multiple stations and time order breaks.** A train that stops at several departure stations (一车多站, e.g. G7357) appears once per stop-time, all grouped adjacently — so you see 08:10 / 08:35 / 08:52 for the same train number and can't scan by time. Hit this in production (thought \"no 08:16 train exists\" — there was one).\n\n**Fix: tap the departure-station filter chip at the top of the list first** (chips row, y≈669-708 on 1080x2400; e.g. 上海松江 / 杭州南 / 上海虹桥 / 上海南):\n\n```python\nchip = [x for x in t if '松江' in x[0] and x[2] < 600]   # OCR: station name near top\nd.click((chip[0][1]+chip[0][3])//2, (chip[0][2]+chip[0][4])//2)\n```\n\nAfter filtering: one row per train, sorted by departure time, target times are findable by simple scrolling.\n\n**⚠️ The filter resets after every re-query** (查询车票) — re-apply the chip each time.\n\n## Booking Flow (proven end-to-end)\n\n### Step 0: Install & Login (only if app missing)\n\n- Download the official APK from the 12306 site (kyfw.12306.cn 下载页), e.g. `curl` the direct link → `adb install -r app.apk`\n- The user must log in manually (SMS/face) — automation cannot do this step.\n\n### Step 1: Home Page — Stations & Date\n\nStations: tap the station field → search box opens. **Chinese input via clipboard** (IME switching is blocked):\n\n```bash\n$PY ocr_bridge.py type 苏州 --x 400 --y 330   # set_clipboard + long-press field\n$PY ocr_bridge.py dump                        # find 粘贴 in OCR\n$PY ocr_bridge.py tap-text 粘贴               # paste → results appear\n$PY ocr_bridge.py tap-text 苏州站              # pick the main station\n```\n\nDate: the date picker opens with day cells — OCR the month grid and tap the day cell (e.g. tomorrow's cell right of 今天).\n\n### Step 2: Query & Navigate the Train List\n\nTap 查询车票. The list loads with earliest departures first.\n\n```bash\n$PY ocr_bridge.py deps        # HH:MM markers at x<250 = which time window is visible\n$PY ocr_bridge.py swipe up --scale 0.35     # normal forward scroll (≈2 cards)\n```\n\n- Track position with `deps` — you always know where you are, DOM or not.\n- **Apply the departure-station filter chip FIRST** (see section above) — without it the list is not time-ordered.\n- **Filter further if available**: tap 只看高铁/动车 (or 只看高铁) to shorten the list.\n- **List keeps skipping the target section**: `$PY ocr_bridge.py jump --n 3` (3 rapid scale-0.5 swipes breaks the stuck point), then micro-swipes back: `swipe up --scale 0.25`, `micro down`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`.\n- Trains to your destination: match OCR train numbers with regex `^[GDCK]\\d+` plus the destination name in the row text (ignore trains to other destinations, e.g. 太仓 when heading to 苏州).\n\n### Step 3: Expand Card & Tap the Row's 预订\n\n- Tap the target card's seat-row label (二等) to expand → verify expansion by OCR (prices ￥41 etc. appear).\n- Tap the expanded row's 预订 on the right edge.\n- If a quiet-carriage dialog appears (静音车厢 rules) → tap its confirm button (选择/继续).\n\n### Step 4: Select Passenger\n\n- On the 确认订单 page, verify train info + price via OCR markers.\n- Tap 选择乘车人 → passenger list appears → `tap-text <name>` (e.g. 熊天放).\n- Verify selection: OCR shows 已选 next to the name.\n- Tap 确认 / 完成 (bottom button).\n\n### Step 5: Submit Order & Verify\n\n```bash\n$PY ocr_bridge.py tap-text 提交订单\n$PY ocr_bridge.py wait-text 订单处理中      # order processing\n$PY ocr_bridge.py markers                   # look for 快速支付 / 立即支付\n```\n\n- `订单处理中` → wait and re-OCR (can take ~20-60s).\n- `快速支付` or `立即支付` + countdown at top = **order locked, success**. Report: train, date, route, seat, price, passenger, seat number, countdown.\n- **Payment is manual**: the user pays in Alipay/WeChat on the phone (指纹/密码 can't be automated). Typical lock window ≈19 minutes.\n\n### 车票信息已过期 (M0013) — Recovery\n\nIf the list data sat too long before submitting, the order page throws **\"车票信息已过期(M0013)\"**. Detect it by polling markers after 提交订单:\n\n```python\nfor i in range(8):\n    time.sleep(4)\n    markers = [x[0] for x in shot() if any(k in x[0] for k in\n               ('立即支付','快速支付','订单处理','温馨提示','取消订单','已过期','确定'))]\n    if any('已过期' in m or '确定' in m for m in markers): break   # ERROR\n    if any('立即支付' in m for m in markers): break                # SUCCESS\n```\n\nRecovery (proven):\n\n1. Tap **确定** on the dialog.\n2. `d.press('back')` ×2 → home page. (Pull-to-refresh on the list did NOT refresh the data — don't bother.)\n3. Tap **查询车票** for a full re-query → fresh list.\n4. **Re-apply the departure-station filter chip** (it resets on re-query).\n5. Scroll to the train → expand → 预订 → passenger → 提交订单. Fresh data submits without the error.\n\n## Scroll Tactics Cheat Sheet\n\n| Situation | Command |\n|-----------|---------|\n| Normal advance | `swipe up --scale 0.35` |\n| Fine-tune position | `micro up` / `micro down` (scale 0.15) |\n| Precise pixel scroll | `d.swipe(540, 1900, 540, 800, duration=0.4)` |\n| List stuck / skips target window | `jump --n 3`, then micro back |\n| Back up a little | `swipe down --scale 0.3` |\n\n## Decision Tree\n\n```\nOCR markers:\n  ├─ 查询车票                    → HOME — set stations/date → tap 查询车票\n  ├─ 提交订单 / 选择乘车人        → ORDER PAGE — passenger → 提交订单\n  ├─ 订单处理中                  → wait, re-OCR\n  ├─ 车票信息已过期 / 确定对话框  → EXPIRED — 确定 → back → 查询车票 → re-filter → re-book\n  ├─ 快速支付 / 立即支付          → SUCCESS — tell user to pay\n  ├─ deps() times + train numbers → TRAIN LIST — scroll/find → expand → 预订\n  ├─ 粘贴 menu visible           → after clipboard type, tap 粘贴\n  └─ unknown                     → dump full OCR and re-orient\n```\n\n## 🛡️ Safety & Consent\n\n- Use only when the user explicitly asks to book a ticket — never speculatively.\n- **Confirm before submitting**: show the user the train, date, route, seat,\n  price and passenger, and wait for confirmation before tapping 提交订单.\n- Payment (立即支付, Alipay/WeChat, password/fingerprint) is ALWAYS done by the\n  user on the phone — never automated.\n- Screenshots may contain personal data; they are stored in a private 0700 dir\n  (`~/.cache/ocr-bridge`) — see appium-android-adb for cleanup.\n\n## Common Pitfalls (all hit in production)\n\n1. **Never trust the DOM** — it collapses and lies. OCR every time.\n2. **Raw ADB taps are filtered** by UC WebView — always `d.click`.\n3. **Appium is dead on Realme** (WRITE_SECURE_SETTINGS blocked) — don't waste time on it.\n4. **IME switching blocked** — Chinese input = `set_clipboard` + long-press 粘贴.\n5. **The list skips departure windows** — `jump` past the stuck point, then micro-scroll.\n6. **Clicking 二等 toggles the card** — if it collapsed again, re-expand and click the row's right-edge 预订, not the label.\n7. **Screen auto-lock** — `adb shell svc power stayon true`.\n8. **一车多站 mixes the time order** — same train number appears at multiple departure times (one per 发站), grouped adjacently. Always apply the departure-station filter chip before scanning for a time.\n9. **Stale list → 车票信息已过期(M0013)** — list data expires while you sit on it. Recovery: 确定 → back → full re-query → **re-apply station filter** → re-book. Pull-to-refresh does NOT refresh the data.\n10. **The station filter resets on re-query** — re-apply the chip every time after 查询车票.\n11. **OCR misreads** — filter by region (x/y bounds), re-shoot after animations (sleep 2-3s).\n12. **Train numbers**: OCR gives `G3314` (no spaces); DOM gives `G 3 3 1 4`. Regex on OCR text.\n13. **USB/ADB can drop mid-session** — app state (filter + scroll position) survives; ask the user to replug, then continue where you left off.\n\nFile v2.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"2.2.1\",\n  \"publishedAt\": 1788077575562\n}\n\nFile v2.2.1:skill-card.md\n\n## Description:\n\nGuides an agent through booking train tickets in the 12306 Android app over USB ADB using uiautomator2, OCR, and documented recovery steps for WebView and stale-ticket flows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operators use this skill to help an agent navigate the 12306 Android ticket-booking flow for a user-requested trip. It provides ADB/OCR workflows, train-list handling, passenger selection, submit-order checks, and recovery guidance while keeping login, confirmation, and payment under user control.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can exercise broad ADB control over a logged-in Android phone.\n\nMitigation: Use it only for a specific user-requested booking, verify trip details before submission, and keep final payment manual on the device.\n\nRisk: Screenshots, clipboard contents, and temporary phone files may contain personal travel or passenger data.\n\nMitigation: Clear temporary screenshots, clipboard contents, and /sdcard/_input.txt after use.\n\nRisk: Untrusted text, package names, file paths, or shell commands passed through helper functions could cause unintended device actions.\n\nMitigation: Use trusted, task-specific inputs and review generated commands before execution.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/12306-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with inline bash and Python code blocks]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include ADB commands, OCR-based decision guidance, and manual verification checkpoints.]\n\n## Skill Version(s):\n\n2.2.1 (source: server release evidence)\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 v2.2.0: 5 files, 20684 bytes\n\nFiles: __pycache__/adb_helper.cpython-314.pyc (21785b), _meta.json (136b), adb_helper.py (12244b), skill-card.md (2538b), SKILL.md (10902b)\n\nFile v2.2.0:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: Book train tickets on the 12306 Android app via USB ADB. Battle-tested 2026-08-30 (two successful bookings: G3314 上海→苏州 and D203 上海松江→杭州南). Primary method: direct uiautomator2 + RapidOCR via ocr_bridge.py (see appium-android-adb skill). Covers the UC WebView virtual-list traps, the card-expand UI, departure-station filter (一车多站 time disorder), scroll-unsticking, clipboard Chinese input, and 车票信息已过期 (M0013) recovery.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app (com.MobileTicket) uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges. This doc reflects **two successful end-to-end bookings** on the current app version (2026-08-30, Realme RMX3350 1080x2400).\n\n## 🚨 Setup (proven)\n\n```bash\n# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n**Do NOT use the Appium bridge for 12306 on consumer phones** — Realme etc. block WRITE_SECURE_SETTINGS, so Appium settings/IME fail and the session never starts. Direct uiautomator2 + OCR works (atx-agent needs no special permission). All interaction goes through the OCR loop: `ocr_bridge.py` in the appium-android-adb skill — screenshot → RapidOCR → click/swipe → re-OCR verify.\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView:\n\n- Accessibility tree / DOM is mostly **collapsed** (all non-current items share y≈407 or y≈2255, h=6px) and intermittently renders. Never depend on it.\n- **OCR is the dependable eye**: RapidOCR reads Chinese out of the box (no tesseract language packs needed).\n- Raw `adb shell input tap` is **filtered** by the WebView. `d.click(x, y)` (uiautomator2) reliably delivers touches.\n- The list **skips sections** when scrolling: a departure-time window (e.g. 06:32) can be jumped over repeatedly.\n\n## New-App UI: Card Expansion + Per-Row 预订 (2026-08 version)\n\n**Collapsed train cards have NO 预订 button.** The flow is:\n\n1. Tap the **seat row** of a card (e.g. \"二等\" label area) → the card **expands** in place, showing seat rows: 二等 / 一等 / 商务 / 无座, each with price (e.g. `二等 ¥41 9折`).\n2. Each expanded row has its own **预订 button on the right edge** (on 1080px width: x≈898–980, h≈48, at the row's y).\n3. Tap that row's 预订 → 确认订单 page.\n\n```bash\n# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订\n```\n\n(Example coordinates from the real run: card row at (141, 2026) expanded; 二等 row 预订 at (939, 1987); order page followed.)\n\n## ⚠️ Departure-Station Filter — Do This BEFORE Scrolling (一车多站)\n\n**Without the filter, the list mixes departures from multiple stations and time order breaks.** A train that stops at several departure stations (一车多站, e.g. G7357) appears once per stop-time, all grouped adjacently — so you see 08:10 / 08:35 / 08:52 for the same train number and can't scan by time. Hit this in production (thought \"no 08:16 train exists\" — there was one).\n\n**Fix: tap the departure-station filter chip at the top of the list first** (chips row, y≈669-708 on 1080x2400; e.g. 上海松江 / 杭州南 / 上海虹桥 / 上海南):\n\n```python\nchip = [x for x in t if '松江' in x[0] and x[2] < 600]   # OCR: station name near top\nd.click((chip[0][1]+chip[0][3])//2, (chip[0][2]+chip[0][4])//2)\n```\n\nAfter filtering: one row per train, sorted by departure time, target times are findable by simple scrolling.\n\n**⚠️ The filter resets after every re-query** (查询车票) — re-apply the chip each time.\n\n## Booking Flow (proven end-to-end)\n\n### Step 0: Install & Login (only if app missing)\n\n- Download the official APK from the 12306 site (kyfw.12306.cn 下载页), e.g. `curl` the direct link → `adb install -r app.apk`\n- The user must log in manually (SMS/face) — automation cannot do this step.\n\n### Step 1: Home Page — Stations & Date\n\nStations: tap the station field → search box opens. **Chinese input via clipboard** (IME switching is blocked):\n\n```bash\n$PY ocr_bridge.py type 苏州 --x 400 --y 330   # set_clipboard + long-press field\n$PY ocr_bridge.py dump                        # find 粘贴 in OCR\n$PY ocr_bridge.py tap-text 粘贴               # paste → results appear\n$PY ocr_bridge.py tap-text 苏州站              # pick the main station\n```\n\nDate: the date picker opens with day cells — OCR the month grid and tap the day cell (e.g. tomorrow's cell right of 今天).\n\n### Step 2: Query & Navigate the Train List\n\nTap 查询车票. The list loads with earliest departures first.\n\n```bash\n$PY ocr_bridge.py deps        # HH:MM markers at x<250 = which time window is visible\n$PY ocr_bridge.py swipe up --scale 0.35     # normal forward scroll (≈2 cards)\n```\n\n- Track position with `deps` — you always know where you are, DOM or not.\n- **Apply the departure-station filter chip FIRST** (see section above) — without it the list is not time-ordered.\n- **Filter further if available**: tap 只看高铁/动车 (or 只看高铁) to shorten the list.\n- **List keeps skipping the target section**: `$PY ocr_bridge.py jump --n 3` (3 rapid scale-0.5 swipes breaks the stuck point), then micro-swipes back: `swipe up --scale 0.25`, `micro down`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`.\n- Trains to your destination: match OCR train numbers with regex `^[GDCK]\\d+` plus the destination name in the row text (ignore trains to other destinations, e.g. 太仓 when heading to 苏州).\n\n### Step 3: Expand Card & Tap the Row's 预订\n\n- Tap the target card's seat-row label (二等) to expand → verify expansion by OCR (prices ￥41 etc. appear).\n- Tap the expanded row's 预订 on the right edge.\n- If a quiet-carriage dialog appears (静音车厢 rules) → tap its confirm button (选择/继续).\n\n### Step 4: Select Passenger\n\n- On the 确认订单 page, verify train info + price via OCR markers.\n- Tap 选择乘车人 → passenger list appears → `tap-text <name>` (e.g. 熊天放).\n- Verify selection: OCR shows 已选 next to the name.\n- Tap 确认 / 完成 (bottom button).\n\n### Step 5: Submit Order & Verify\n\n```bash\n$PY ocr_bridge.py tap-text 提交订单\n$PY ocr_bridge.py wait-text 订单处理中      # order processing\n$PY ocr_bridge.py markers                   # look for 快速支付 / 立即支付\n```\n\n- `订单处理中` → wait and re-OCR (can take ~20-60s).\n- `快速支付` or `立即支付` + countdown at top = **order locked, success**. Report: train, date, route, seat, price, passenger, seat number, countdown.\n- **Payment is manual**: the user pays in Alipay/WeChat on the phone (指纹/密码 can't be automated). Typical lock window ≈19 minutes.\n\n### 车票信息已过期 (M0013) — Recovery\n\nIf the list data sat too long before submitting, the order page throws **\"车票信息已过期(M0013)\"**. Detect it by polling markers after 提交订单:\n\n```python\nfor i in range(8):\n    time.sleep(4)\n    markers = [x[0] for x in shot() if any(k in x[0] for k in\n               ('立即支付','快速支付','订单处理','温馨提示','取消订单','已过期','确定'))]\n    if any('已过期' in m or '确定' in m for m in markers): break   # ERROR\n    if any('立即支付' in m for m in markers): break                # SUCCESS\n```\n\nRecovery (proven):\n\n1. Tap **确定** on the dialog.\n2. `d.press('back')` ×2 → home page. (Pull-to-refresh on the list did NOT refresh the data — don't bother.)\n3. Tap **查询车票** for a full re-query → fresh list.\n4. **Re-apply the departure-station filter chip** (it resets on re-query).\n5. Scroll to the train → expand → 预订 → passenger → 提交订单. Fresh data submits without the error.\n\n## Scroll Tactics Cheat Sheet\n\n| Situation | Command |\n|-----------|---------|\n| Normal advance | `swipe up --scale 0.35` |\n| Fine-tune position | `micro up` / `micro down` (scale 0.15) |\n| Precise pixel scroll | `d.swipe(540, 1900, 540, 800, duration=0.4)` |\n| List stuck / skips target window | `jump --n 3`, then micro back |\n| Back up a little | `swipe down --scale 0.3` |\n\n## Decision Tree\n\n```\nOCR markers:\n  ├─ 查询车票                    → HOME — set stations/date → tap 查询车票\n  ├─ 提交订单 / 选择乘车人        → ORDER PAGE — passenger → 提交订单\n  ├─ 订单处理中                  → wait, re-OCR\n  ├─ 车票信息已过期 / 确定对话框  → EXPIRED — 确定 → back → 查询车票 → re-filter → re-book\n  ├─ 快速支付 / 立即支付          → SUCCESS — tell user to pay\n  ├─ deps() times + train numbers → TRAIN LIST — scroll/find → expand → 预订\n  ├─ 粘贴 menu visible           → after clipboard type, tap 粘贴\n  └─ unknown                     → dump full OCR and re-orient\n```\n\n## Common Pitfalls (all hit in production)\n\n1. **Never trust the DOM** — it collapses and lies. OCR every time.\n2. **Raw ADB taps are filtered** by UC WebView — always `d.click`.\n3. **Appium is dead on Realme** (WRITE_SECURE_SETTINGS blocked) — don't waste time on it.\n4. **IME switching blocked** — Chinese input = `set_clipboard` + long-press 粘贴.\n5. **The list skips departure windows** — `jump` past the stuck point, then micro-scroll.\n6. **Clicking 二等 toggles the card** — if it collapsed again, re-expand and click the row's right-edge 预订, not the label.\n7. **Screen auto-lock** — `adb shell svc power stayon true`.\n8. **一车多站 mixes the time order** — same train number appears at multiple departure times (one per 发站), grouped adjacently. Always apply the departure-station filter chip before scanning for a time.\n9. **Stale list → 车票信息已过期(M0013)** — list data expires while you sit on it. Recovery: 确定 → back → full re-query → **re-apply station filter** → re-book. Pull-to-refresh does NOT refresh the data.\n10. **The station filter resets on re-query** — re-apply the chip every time after 查询车票.\n11. **OCR misreads** — filter by region (x/y bounds), re-shoot after animations (sleep 2-3s).\n12. **Train numbers**: OCR gives `G3314` (no spaces); DOM gives `G 3 3 1 4`. Regex on OCR text.\n13. **USB/ADB can drop mid-session** — app state (filter + scroll position) survives; ask the user to replug, then continue where you left off.\n\nFile v2.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"2.2.0\",\n  \"publishedAt\": 1788067357936\n}\n\nFile v2.2.0:skill-card.md\n\n## Description:\n\nBook train tickets on the 12306 Android app via USB ADB using direct uiautomator2 and OCR-based interaction guidance for the app's WebView booking flow.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgents use this skill to guide Android 12306 train-ticket booking workflows on a connected, logged-in phone, including station and date selection, train-list navigation, passenger selection, and order submission checkpoints. It is intended for operators who can supervise booking decisions and complete payment manually.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can control a logged-in Android phone through ADB and may modify app state or initiate real train reservations.\n\nMitigation: Require explicit operator confirmation of train, date, route, passenger, seat class, and price before tapping the order submission control.\n\nRisk: The booking flow can lock a real order that still requires payment outside the agent workflow.\n\nMitigation: Stop after order lock or payment prompt and tell the operator to complete or cancel payment manually on the phone.\n\nRisk: Clipboard-based Chinese text entry can leave sensitive input available to other apps after use.\n\nMitigation: Use clipboard entry only when needed and clear or overwrite the clipboard after completing the relevant field.\n\nRisk: OCR and WebView virtual-list behavior can cause the agent to tap the wrong train, station, passenger, or seat row.\n\nMitigation: Re-OCR after navigation and require visual confirmation before any action that books, changes, or submits an order.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/12306-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Code, Configuration instructions]\n\n**Output Format:** [Markdown guidance with inline bash and Python snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires a connected Android device with ADB access and a manually logged-in 12306 app.]\n\n## Skill Version(s):\n\n2.2.0 (source: evidence.release.version; artifact/_meta.json lists 2.0.0)\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 v2.1.0: 5 files, 19420 bytes\n\nFiles: __pycache__/adb_helper.cpython-314.pyc (21785b), _meta.json (136b), adb_helper.py (12244b), skill-card.md (2499b), SKILL.md (7852b)\n\nFile v2.1.0:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: Book train tickets on the 12306 Android app via USB ADB. Battle-tested 2026-08-30 (booked G3314 上海→苏州 end-to-end). Primary method: direct uiautomator2 + RapidOCR via ocr_bridge.py (see appium-android-adb skill). Covers the UC WebView virtual-list traps, the new card-expand UI, scroll-unsticking, clipboard Chinese input, and the full booking flow.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app (com.MobileTicket) uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges. This doc reflects a **successful end-to-end booking** on the current app version (2026-08-30, Realme RMX3350 1080x2400).\n\n## 🚨 Setup (proven)\n\n```bash\n# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n**Do NOT use the Appium bridge for 12306 on consumer phones** — Realme etc. block WRITE_SECURE_SETTINGS, so Appium settings/IME fail and the session never starts. Direct uiautomator2 + OCR works (atx-agent needs no special permission). All interaction goes through the OCR loop: `ocr_bridge.py` in the appium-android-adb skill — screenshot → RapidOCR → click/swipe → re-OCR verify.\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView:\n\n- Accessibility tree / DOM is mostly **collapsed** (all non-current items share y≈407 or y≈2255, h=6px) and intermittently renders. Never depend on it.\n- **OCR is the dependable eye**: RapidOCR reads Chinese out of the box (no tesseract language packs needed).\n- Raw `adb shell input tap` is **filtered** by the WebView. `d.click(x, y)` (uiautomator2) reliably delivers touches.\n- The list **skips sections** when scrolling: a departure-time window (e.g. 06:32) can be jumped over repeatedly.\n\n## New-App UI: Card Expansion + Per-Row 预订 (2026-08 version)\n\n**Collapsed train cards have NO 预订 button.** The flow is:\n\n1. Tap the **seat row** of a card (e.g. \"二等\" label area) → the card **expands** in place, showing seat rows: 二等 / 一等 / 商务 / 无座, each with price (e.g. `二等 ¥41 9折`).\n2. Each expanded row has its own **预订 button on the right edge** (on 1080px width: x≈898–980, h≈48, at the row's y).\n3. Tap that row's 预订 → 确认订单 page.\n\n```bash\n# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订\n```\n\n(Example coordinates from the real run: card row at (141, 2026) expanded; 二等 row 预订 at (939, 1987); order page followed.)\n\n## Booking Flow (proven end-to-end)\n\n### Step 0: Install & Login (only if app missing)\n\n- Download the official APK from the 12306 site (kyfw.12306.cn 下载页), e.g. `curl` the direct link → `adb install -r app.apk`\n- The user must log in manually (SMS/face) — automation cannot do this step.\n\n### Step 1: Home Page — Stations & Date\n\nStations: tap the station field → search box opens. **Chinese input via clipboard** (IME switching is blocked):\n\n```bash\n$PY ocr_bridge.py type 苏州 --x 400 --y 330   # set_clipboard + long-press field\n$PY ocr_bridge.py dump                        # find 粘贴 in OCR\n$PY ocr_bridge.py tap-text 粘贴               # paste → results appear\n$PY ocr_bridge.py tap-text 苏州站              # pick the main station\n```\n\nDate: the date picker opens with day cells — OCR the month grid and tap the day cell (e.g. tomorrow's cell right of 今天).\n\n### Step 2: Query & Navigate the Train List\n\nTap 查询车票. The list loads with earliest departures first.\n\n```bash\n$PY ocr_bridge.py deps        # HH:MM markers at x<250 = which time window is visible\n$PY ocr_bridge.py swipe up --scale 0.35     # normal forward scroll (≈2 cards)\n```\n\n- Track position with `deps` — you always know where you are, DOM or not.\n- **Filter first if available**: tap 只看高铁/动车 (or 只看高铁) to shorten the list.\n- **List keeps skipping the target section**: `$PY ocr_bridge.py jump --n 3` (3 rapid scale-0.5 swipes breaks the stuck point), then micro-swipes back: `swipe up --scale 0.25`, `micro down`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`.\n- Trains to 苏州: match OCR train numbers with regex `^[GDCK]\\d+` plus 苏州 in the row text (ignore trains to other destinations like 太仓).\n\n### Step 3: Expand Card & Tap the Row's 预订\n\n- Tap the target card's seat-row label (二等) to expand → verify expansion by OCR (prices ￥41 etc. appear).\n- Tap the expanded row's 预订 on the right edge.\n- If a quiet-carriage dialog appears (静音车厢 rules) → tap its confirm button (选择/继续).\n\n### Step 4: Select Passenger\n\n- On the 确认订单 page, verify train info + price via OCR markers.\n- Tap 选择乘车人 → passenger list appears → `tap-text <name>` (e.g. 熊天放).\n- Verify selection: OCR shows 已选 next to the name.\n- Tap 确认 / 完成 (bottom button).\n\n### Step 5: Submit Order & Verify\n\n```bash\n$PY ocr_bridge.py tap-text 提交订单\n$PY ocr_bridge.py wait-text 订单处理中      # order processing\n$PY ocr_bridge.py markers                   # look for 快速支付 / 立即支付\n```\n\n- `订单处理中` → wait and re-OCR (can take ~20-60s).\n- `快速支付` or `立即支付` + countdown at top = **order locked, success**. Report: train, date, route, seat, price, passenger, seat number, countdown.\n- **Payment is manual**: the user pays in Alipay/WeChat on the phone (指纹/密码 can't be automated). Typical lock window ≈19 minutes.\n\n## Scroll Tactics Cheat Sheet\n\n| Situation | Command |\n|-----------|---------|\n| Normal advance | `swipe up --scale 0.35` |\n| Fine-tune position | `micro up` / `micro down` (scale 0.15) |\n| Precise pixel scroll | `d.swipe(540, 1900, 540, 800, duration=0.4)` |\n| List stuck / skips target window | `jump --n 3`, then micro back |\n| Back up a little | `swipe down --scale 0.3` |\n\n## Decision Tree\n\n```\nOCR markers:\n  ├─ 查询车票                    → HOME — set stations/date → tap 查询车票\n  ├─ 提交订单 / 选择乘车人        → ORDER PAGE — passenger → 提交订单\n  ├─ 订单处理中                  → wait, re-OCR\n  ├─ 快速支付 / 立即支付          → SUCCESS — tell user to pay\n  ├─ deps() times + train numbers → TRAIN LIST — scroll/find → expand → 预订\n  ├─ 粘贴 menu visible           → after clipboard type, tap 粘贴\n  └─ unknown                     → dump full OCR and re-orient\n```\n\n## Common Pitfalls (all hit in production)\n\n1. **Never trust the DOM** — it collapses and lies. OCR every time.\n2. **Raw ADB taps are filtered** by UC WebView — always `d.click`.\n3. **Appium is dead on Realme** (WRITE_SECURE_SETTINGS blocked) — don't waste time on it.\n4. **IME switching blocked** — Chinese input = `set_clipboard` + long-press 粘贴.\n5. **The list skips departure windows** — `jump` past the stuck point, then micro-scroll.\n6. **Clicking 二等 toggles the card** — if it collapsed again, re-expand and click the row's right-edge 预订, not the label.\n7. **Screen auto-lock** — `adb shell svc power stayon true`.\n8. **Page timeout** — after ~5 min idle the list needs re-query.\n9. **OCR misreads** — filter by region (x/y bounds), re-shoot after animations (sleep 2-3s).\n10. **Train numbers**: OCR gives `G3314` (no spaces); DOM gives `G 3 3 1 4`. Regex on OCR text.\n\nFile v2.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"2.1.0\",\n  \"publishedAt\": 1788063419712\n}\n\nFile v2.1.0:skill-card.md\n\n## Description:\n\nBook train tickets on the 12306 Android app via USB ADB using uiautomator2 and OCR guidance for WebView navigation, card expansion, passenger selection, and order submission.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to guide an agent controlling a connected Android phone through the 12306 train-ticket booking flow. The user remains responsible for login, payment, and final approval before order submission.\n\n### Deployment Geography for Use:\n\nGlobal, for users booking China Railway 12306 tickets.\n\n## Known Risks and Mitigations:\n\nRisk: The skill can guide an agent to submit real train reservations in a signed-in 12306 account.\n\nMitigation: Require explicit user confirmation immediately before any Submit Order action, and keep payment as a manual user step.\n\nRisk: ADB-level phone control can affect apps or screens outside the intended 12306 booking flow.\n\nMitigation: Run only on a supervised connected device, avoid sensitive screens during the session, and stop the agent if it leaves the expected app flow.\n\nRisk: APK installation or app launch steps may involve trusting software on the phone.\n\nMitigation: Have the user approve any APK installation directly and verify the app source before proceeding.\n\nRisk: Screenshots, UI dumps, and clipboard operations may temporarily expose account, passenger, or travel details.\n\nMitigation: Clear temporary screenshots, UI dumps, and clipboard contents after the session.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/openlittlebear/skills/12306-android-adb)\n- [Skill Source](artifact/SKILL.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and Python snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include ADB and uiautomator2 actions that require a connected Android device, an installed 12306 app, and user-approved account actions.]\n\n## Skill Version(s):\n\n2.1.0 (source: server release evidence)\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.0.1: 4 files, 9007 bytes\n\nFiles: _meta.json (136b), adb_helper.py (10786b), skill-card.md (2101b), SKILL.md (8559b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: 12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Uses appium-android-adb bridge OR direct uiautomator2 for all interaction.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges.\n\n## 🚨 Before Any 12306 Action\n\nEnsure the app is running and on the correct page:\n\n```bash\n# Start Appium bridge (if using bridge_daemon.py approach):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Or use uiautomator2 directly (more reliable for WebView):\npython3 -c \"import uiautomator2 as u2; d = u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView. This has extreme implications:\n\n### What DOES work\n| Method | Target | Reliability |\n|--------|--------|-------------|\n| `uiautomator2 text('预订').click()` | \"预订\" book buttons | ✅ Always works (proper persistent bounds) |\n| `uiautomator2 text('查询车票').click()` | Native query button | ✅ Always works |\n| `uiautomator2 text('选择乘车人').click()` | Native passenger selector | ✅ Always works |\n| `uiautomator2.click(x, y)` on native views | Date tabs, bottom buttons | ✅ Always works |\n| Screenshot + OCR + ADB tap | Any visible element | ✅ Works with good OCR |\n| `Appium element.click()` on \"预订\" buttons | \"预订\" with proper bounds | ✅ Works |\n\n### What DOES NOT work\n| Method | Target | Why |\n|--------|--------|-----|\n| Clicking collapsed train name text | Train entry at y=407 or y=2255 (h=6) | Virtual list collapses ALL non-current items |\n| ADB `input tap` | Any UC WebView content | UC WebView filters synthetic touch events |\n| W3C Actions swipe | UC WebView scroll | Touch events filtered |\n| `mobile: scrollGesture` | UC WebView element | Returns False consistently |\n| `d.textContains('G 7 0 0 4').click()` | Train name in collapsed zone | Multiple trains share collapsed bounds |\n| `tap_bounds` on collapsed element | Train name at y=2255 with h=6 | Event goes to WebView's virtual position, not visual |\n\n### Key Insight: \"预订\" Buttons Have Proper Bounds\n\nThe ONLY reliable click targets in the UC WebView train list are the **\"预订\" action buttons**. Unlike the text content (train name, times, seat info) which gets collapsed by the virtual list, the \"预订\" button is:\n- Always rendered with proper bounds (h=87px)\n- Clickable via accessibility service\n- Positioned consistently ~195px below each train card's top\n- Unique per train card (find the one nearest your target train's y-position)\n\n## Booking Flow\n\n### Step 1: Home Page — Search Trains\n\n```\ndump the page → check for \"查询车票\" button\nIf on MainActivity:\n  → tap \"查询车票\" (native button, always works)\n  → wait for train list to load (H5Activity appears)\nIf on H5Activity (already on train list):\n  → proceed to Step 2\n```\n\n### Step 2: Find Target Train's \"预订\" Button\n\n**DO NOT try to click the train name or text content.** Instead:\n\n1. **Scroll** the list until you see trains near your target departure time:\n   ```python\n   d.swipe_ext('up', scale=0.3)   # scroll forward\n   d.swipe_ext('down', scale=0.3)  # scroll backward\n   ```\n\n2. **Check for G7004 in the DOM** (even collapsed):\n   ```python\n   xml = d.dump_hierarchy()\n   if 'G 7 0 0 4' in xml:\n       # G7004 is in the list — look for its \"预订\" button\n       pass\n   ```\n\n3. **Find the \"预订\" button** associated with your train. \"预订\" buttons appear at regular y-intervals (~315px apart). The one closest to your target train's y-position belongs to that train:\n   ```python\n   # Get all \"预订\" buttons with positions\n   buttons = d(text='预订')\n   for btn in buttons:\n       pos = btn.info['bounds']\n       y_center = (pos['top'] + pos['bottom']) // 2\n       print(f\"预订 at y={y_center}\")\n\n   # G7004 at y=1793 → the \"预订\" at y=1988 is its book button\n   ```\n\n4. **Click \"预订\":**\n   ```python\n   d(text='预订').click()          # clicks first one\n   # OR click specific one by position:\n   for btn in d(text='预订'):\n       if 1900 < btn.info['bounds']['top'] < 2100:\n           btn.click()\n           break\n   ```\n\n### Step 2b: OCR-Based Fallback (if DOM is unreliable)\n\nIf the WebView's DOM is too collapsed to find the right \"预订\":\n\n```python\nimport subprocess, pytesseract\nfrom PIL import Image\n\n# Take screenshot\nsubprocess.run(['adb', 'shell', 'screencap', '-p', '/sdcard/screen.png'], timeout=10)\nsubprocess.run(['adb', 'pull', '/sdcard/screen.png', '/tmp/screen.png'], timeout=10)\n\n# OCR to find departure time\ndata = pytesseract.image_to_data(Image.open('/tmp/screen.png'),\n    lang='chi_sim+eng', output_type=pytesseract.Output.DICT, config='--psm 6')\n\n# Find \"08:00\" departure text on LEFT side (x < 300)\nfor i in range(len(data['text'])):\n    if '08:00' in data['text'][i] and int(data['left'][i]) < 300:\n        y = data['top'][i]\n        # Tap \"预订\" position (~195px below departure time)\n        import subprocess\n        subprocess.run(['adb', 'shell', 'input', 'tap', '939', str(y + 195)])\n        break\n```\n\n### Step 3: Quiet Carriage Dialog (if appears)\n\nAfter clicking \"预订\", a dialog may appear:\n- \"选择该车次二等座可能候补到静音车厢席位，是否继续选择？\" → tap \"继续\" or \"选择\"\n- \"温馨提示\" with quiet carriage rules → tap \"选择\" (bottom-right button)\n\nUse OCR to find the confirm button position, then ADB tap it.\n\n### Step 4: Select Passenger\n\n```\nOn order page, verify:\n  → G7004 train info displayed\n  → 二等座 selected (default)\n  → Price ¥41 shown\n\nIf no passenger selected:\n  → tap \"选择乘车人\" (native, works)\n  → tap passenger name (e.g. \"熊子慧\")\n  → tap \"确认\" (bottom button)\n```\n\n### Step 5: Submit Order\n\n```\ntap \"提交订单\" button\n  → verify: order submission confirmation\n  → if \"温馨提示\" with \"车票信息已过期\" → go back, re-search\n  → if \"立即支付\" → proceed to payment\n```\n\n### Step 6: Payment (manual)\n\n```\n\"立即支付\" or \"去支付\" appears → user handles Alipay/WeChat\n```\n\n## Train List Navigation (Scrolling)\n\nThe UC WebView's virtual list has three zones:\n- **Top collapsed** (y=407, h=6): Items scrolled past the top\n- **Proper viewport** (y=500-2200, h=60-130): Currently visible items with real bounds\n- **Bottom collapsed** (y=2255, h=6): Items below the viewport\n\nEach scroll (scale=0.3) advances the list by approximately 2 train cards (~30-60 min of departures). To reach a specific train:\n1. Start from the earliest visible time\n2. Calculate approximate scrolls needed: `(target_hour - current_hour) * 60 / 15` (each scroll ≈ 15 min of departures)\n3. Scroll, then check for target text in DOM (even collapsed)\n4. Once target text appears in DOM, look for its \"预订\" button\n\n## Decision Tree\n\n```\ndump / check current page:\n  ├─ package != \"com.MobileTicket\"\n  │   → app not running, start it\n  ├─ \".ui.activity.MainActivity\" in activity\n  │   → HOME PAGE\n  │   → verify stations are set → tap \"查询车票\"\n  ├─ \"H5Activity\" in activity\n  │   ├─ \"提交订单\" in text → ORDER CONFIRMATION\n  │   │   → select passenger if needed → submit\n  │   ├─ \"预订\" in text → TRAIN LIST (with \"预订\" buttons)\n  │   │   → find target train → click its \"预订\" button\n  │   ├─ \"次列车\" in text → TRAIN LIST (loading)\n  │   │   → scroll until target appears → find \"预订\"\n  │   └─ \"立即支付\" in text → PAYMENT\n  │       → user handles payment\n  └─ anything else → not 12306, investigate\n```\n\n## Common Pitfalls\n\n1. **NEVER click collapsed train names** — they all share the same y=407 or y=2255 bounds. Click the \"预订\" button instead.\n2. **\"预订\" buttons have proper bounds** — they're the only reliable WebView targets.\n3. **Screen may auto-lock** — keep device awake: `adb shell svc power stayon true`\n4. **Session conflicts** — Appium and uiautomator2 can't run simultaneously (both need AccessibilityService).\n5. **Page may time out** — if no action for ~5 min, the list might need re-querying.\n6. **Date tabs are native** — tapping \"05月31日 周日\" at bounds [189,257][312,383] always works.\n7. **Train numbers have spaces** — search for `G 7 0 0 4` not `G7004`.\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1780271601128\n}\n\nFile v1.0.1:skill-card.md\n\n## Description: <br>\n12306-specific knowledge for booking train tickets via the Android app, including UC WebView virtual list behavior, a proven booking flow, and common automation pitfalls. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[openlittlebear](https://clawhub.ai/user/openlittlebear) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and automation operators use this skill to guide Android-based 12306 train ticket booking through ADB or uiautomator2, including train search, booking-button selection, passenger selection, order submission, and manual handoff for payment. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can control a real Android phone and submit ticket orders. <br>\nMitigation: Use a test or dedicated Android device and account where possible, and require the user to confirm every booking step before order submission. <br>\nRisk: Screenshot and OCR fallback can capture payment details, messages, one-time codes, or other private data. <br>\nMitigation: Avoid sensitive screens when using screenshot or OCR fallback, and delete local /tmp screenshots and on-device temporary files after use. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/12306-android-adb) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, guidance] <br>\n**Output Format:** [Markdown guidance with inline shell and Python code blocks] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May include Android UI automation steps, ADB commands, uiautomator2 snippets, and manual payment handoff guidance.] <br>\n\n## Skill Version(s): <br>\n1.0.1 (source: server-resolved release metadata) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nArchive v1.0.0: 5 files, 8794 bytes\n\nFiles: _meta.json (136b), adb_helper.py (10786b), README.md (2232b), skill-card.md (2270b), SKILL.md (4964b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: 12306-android-adb\ndescription: 12306-specific knowledge for booking train tickets. Covers app UI structure, station search behavior, booking flow, and common pitfalls. Uses the appium-android-adb bridge for all screen interaction — NEVER use raw ADB commands on 12306.\n---\n\n# 12306 Train Booking\n\n12306-specific knowledge, workflows, and pitfalls. For screen interaction, use the `appium-android-adb` skill (`bridge_daemon.py`).\n\n## 🚨 Before Any 12306 Action\n\nStart the Appium bridge (once per session):\n\n```bash\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n```\n\nAll screen interactions use `python3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py <command>`.\n\n## ⚠ Never Use Raw ADB on 12306\n\nThe 12306 app uses UC WebView for the train list and booking pages. **ADB `input tap` is IGNORED.** Always use `bridge_daemon.py` from `appium-android-adb`.\n\n## 12306 App Structure\n\n| Page | Package/Activity | How to Detect |\n|------|-----------------|---------------|\n| Home | `com.MobileTicket` / `MainActivity` | `ticket_home_btn_search` button exists |\n| Train list | `com.MobileTicket` / `H5Activity` | `title` contains `<>` (e.g. \"上海 <> 苏州\") |\n| Booking | same H5Activity | \"预订\" buttons exist |\n| Confirmation | same H5Activity | \"提交订单\" button exists |\n| Payment | same H5Activity | \"立即支付\" or \"去支付\" button |\n\n### Key Element IDs (Home Page)\n\n| Element | Resource ID |\n|---------|------------|\n| Search button | `ticket_home_btn_search` |\n| Departure station | `home_page_train_dep1` |\n| Arrival station | `home_page_train_arr1` |\n| Date container | `home_page_depart_date_view_container` |\n\n## ⚠ Station Search Behavior\n\n**Any station in a city searches ALL stations in that city.** Example:\n- \"上海虹桥→苏州\" also shows trains from 上海站, 上海南站, 上海松江 etc.\n- \"上海→苏州北\" also shows trains to 苏州站, 苏州园区, 苏州新区 etc.\n\n**Once you have ANY valid city-to-city search result, NEVER go back to change stations.** If the target train isn't immediately visible, just scroll — it's in the list.\n\n## Booking Flow\n\n### Step 1: Home page — ensure valid city pair + date\n```\ndump → check current stations and date\nIf stations show any valid city pair (e.g. \"上海虹桥→苏州\" or \"上海→苏州北\"):\n  → SKIP station changes. All trains from both cities will appear.\nIf stations are completely wrong:\n  → tap departure, pick ANY station in correct city\n  → tap arrival, pick ANY station in correct city\ntap date container → pick target date\ntap \"查询车票\"\n```\n\n### Step 2: Find and select train\n```\ndump → check trains[] for target train number\nscroll down → dump → repeat until target appears\ntap train by text (e.g. '{\"text\": \"G7004\"}')\n→ train detail / booking page appears\n```\n\n### Step 3: Book seat\n```\ndump → see seat options, look for \"预订\" buttons\ntap '{\"text\": \"预订\", \"index\": 0}'  → first is usually 二等座\n```\n\n### Step 4: Fingerprint (manual — tell user)\n```\nIf alert with \"指纹\" appears: tell user to authenticate on phone. Wait, then dump to verify.\n```\n\n### Step 5: Confirm and submit\n```\ndump → verify train, passenger, seat, price\nIf passenger not selected: tap \"选择乘车人\" → tap passenger name\ntap \"提交订单\"\n```\n\n### Step 6: Payment (user handles Alipay/WeChat)\n```\ndump → tap \"立即支付\" or \"去支付\"\n→ User handles Alipay/WeChat login manually\n```\n\n## Decision Tree\n\n```\ndump the screen:\n  ├─ package != \"com.MobileTicket\" → app not in foreground, tap app icon or adb shell monkey\n  ├─ \"ticket_home_btn_search\" in buttons → HOME PAGE\n  │   → ensure valid city pair (any station!) + date → tap 查询车票\n  ├─ title contains \"<>\" → TRAIN LIST\n  │   → scroll + dump to find target train → tap it\n  │   → NEVER go back to change stations — scroll instead\n  ├─ \"预订\" in buttons → BOOKING PAGE\n  │   → tap 预订 for seat type\n  ├─ \"提交订单\" in buttons → CONFIRMATION\n  │   → verify details → select passenger → submit\n  ├─ \"立即支付\" in buttons → PAYMENT\n  │   → tap to pay, user handles auth\n  └─ alerts not empty → dismiss first, re-dump\n```\n\n## Common Pitfalls\n\n- **Going back to change stations**: Don't. Any station in a city shows all trains. Just scroll.\n- **Train at viewport edge (h=6)**: Scroll slightly to bring it into view, then tap.\n- **Fingerprint dialog**: Cannot automate. Tell user to authenticate.\n- **Session timeout**: The bridge daemon holds a persistent session — no timeout issues.\n- **Wrong date on train list**: The results page has date tabs at the top. Tap the correct date there directly.\n\n## Files\n\n- `adb_helper.py` — Low-level ADB helper (native element dump/find/tap/swipe). Use for pre-Appium checks or native-only pages.\n- `SKILL.md` — This file. 12306-specific knowledge.\n- `README.md` — Reference docs.\n\nFile v1.0.0:README.md\n\n# 12306 Android ADB 火车票自动化\n\n## 工作原理\n\n12306 App 是混合架构：\n- **首页**：原生 Android 控件 → ADB tap 有效\n- **车次列表**：UC WebView → ADB tap 被过滤，需 uiautomator2\n- **购票/支付**：WebView\n\n### 核心发现\n\n12306 App 使用的 UC WebView 会过滤 ADB 注入的触摸事件（`input tap`、`motionevent`、`monkey`、`sendevent` 全部失败）。只有通过 **AccessibilityService** 发起的点击（uiautomator2）才能在 WebView 上生效。\n\n## 安装\n\n```bash\ncd ~/.openclaw/workspace/skills/12306-android-adb\npip3 install uiautomator2\npython3 -m uiautomator2 init  # 手机上安装 ATX Agent (需要解锁屏幕)\n```\n\n## 使用\n\n### 1. 查询车次\n```bash\n# 查询明天早上 6-10 点的车次（无需 uiautomator2 agent）\npython3 book_12306.py --date 2026-05-19 --time-min 06:00 --time-max 10:00 --list-only\n```\n\n### 2. 预订车票（需要 uiautomator2）\n```bash\npython3 book_12306.py --train G7004 --passenger 熊天放 --date 2026-05-19\n```\n\n### 3. 试运行（在指纹验证前停止）\n```bash\npython3 book_12306.py --train G7004 --dry-run\n```\n\n## 流程\n\n| 步骤 | 操作 | 方式 | 自动化 |\n|------|------|------|--------|\n| 1 | 打开 App 首页 | ADB native | ✅ |\n| 2 | 设置日期/站点 | ADB native | ✅ |\n| 3 | 查询车票 | ADB native | ✅ |\n| 4 | 滚动到目标车次 | ADB swipe | ✅ |\n| 5 | 点击车次 | **uiautomator2** | ✅ |\n| 6 | **指纹验证** | 物理指纹 | ❌ |\n| 7 | 选择座位/乘客 | uiautomator2 | ✅ |\n| 8 | 提交订单 | uiautomator2 | ✅ |\n\n## 技术调查总结\n\n本次调查确认了 OpenClaw 失败的原因：\n\n1. **UC WebView 拒绝 ADB 触摸事件** — 这是根本原因。所有 `input tap`、`motionevent`、`sendevent`、`monkey` 方法都尝试过，全部无法在车次列表 WebView 中触发点击。\n\n2. **uiautomator2 使用 AccessibilityService 点击** — 这是解决方案。通过 `d(textContains=\"G7004\").click()` 成功导航到购票页。\n\n3. **成功订到 G7004** — 2026-05-19 08:00 上海→苏州，二等座有票，一等座余票 2 张。\n\n4. **指纹验证无法绕过的安全边界** — 12306 要求物理指纹验证，这是自动化必须停止的点。\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1779807568926\n}\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nGuides agents through booking train tickets in the 12306 Android app, including app structure, station search behavior, booking flow, and the requirement to use the Appium Android ADB bridge for screen interaction. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[openlittlebear](https://clawhub.ai/user/openlittlebear) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and external users use this skill to guide an agent through 12306 Android train-ticket search and booking workflows on a connected device, while preserving manual checkpoints for fingerprint authentication and payment. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can give an agent broad control over a connected Android device and a live 12306 account. <br>\nMitigation: Use a dedicated device or session, keep unrelated personal and financial apps inaccessible, and review the skill before installation. <br>\nRisk: The workflow can automate real passenger selection, ticket order submission, and payment entry points. <br>\nMitigation: Require dry runs and explicit confirmation before passenger selection, order submission, or payment, and keep fingerprint authentication and payment completion manual. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/12306-android-adb) <br>\n- [Artifact README](artifact/README.md) <br>\n- [Artifact SKILL](artifact/SKILL.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [guidance, markdown, code, shell commands, configuration] <br>\n**Output Format:** [Markdown guidance with inline shell and Python examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a connected Android device and manual user action for fingerprint authentication and payment.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: server release metadata and artifact _meta.json) <br>\n\n## Ethical Considerations: <br>\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. <br>","readmeExcerpt":"Skill: 12306 Android Adb Owner: openlittlebear Summary: 12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us... Tags: 12306:1.0.0, android:1.0.0, booking:1.0.0, latest:2.2.2, train:1.0.0 Version history: v2.2.2 | 2026-08-30T08:31:54.865Z | user skillSpector cleanup: removed unproven raw-shell patterns (adb input t","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\""},{"language":"bash","snippet":"# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订"},{"language":"python","snippet":"chip = [x for x in t if '松江' in x[0] and x[2] < 600]   # OCR: station name near top\nd.click((chip[0][1]+chip[0][3])//2, (chip[0][2]+chip[0][4])//2)"},{"language":"bash","snippet":"$PY ocr_bridge.py type 苏州 --x 400 --y 330   # set_clipboard + long-press field\n$PY ocr_bridge.py dump                        # find 粘贴 in OCR\n$PY ocr_bridge.py tap-text 粘贴               # paste → results appear\n$PY ocr_bridge.py tap-text 苏州站              # pick the main station"},{"language":"bash","snippet":"$PY ocr_bridge.py deps        # HH:MM markers at x<250 = which time window is visible\n$PY ocr_bridge.py swipe up --scale 0.35     # normal forward scroll (≈2 cards)"},{"language":"bash","snippet":"$PY ocr_bridge.py tap-text 提交订单\n$PY ocr_bridge.py wait-text 订单处理中      # order processing\n$PY ocr_bridge.py markers                   # look for 快速支付 / 立即支付"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: 12306-android-adb\ndescription: Book train tickets on the 12306 Android app via USB ADB. Battle-tested 2026-08-30 (two successful bookings: G3314 上海→苏州 and D203 上海松江→杭州南). Primary method: direct uiautomator2 + RapidOCR via ocr_bridge.py (see appium-android-adb skill). Covers the UC WebView virtual-list traps, the card-expand UI, departure-station filter (一车多站 time disorder), scroll-unsticking, clipboard Chinese input, and 车票信息已过期 (M0013) recovery.\n---\n\n# 12306 Train Booking (Android)\n\n12306-specific knowledge, workflows, and pitfalls. The app (com.MobileTicket) uses Alipay Nebula UC WebView for the train list and booking pages, which has unique automation challenges. This doc reflects **two successful end-to-end bookings** on the current app version (2026-08-30, Realme RMX3350 1080x2400).\n\n## 🚨 Setup (proven)\n\n```bash\n# venv (one-time):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n# App must be installed + logged in. If missing, see \"Install & Login\".\n$PY -c \"import uiautomator2 as u2; d=u2.connect(); d.app_start('com.MobileTicket')\"\n```\n\n**Do NOT use the Appium bridge for 12306 on consumer phones** — Realme etc. block WRITE_SECURE_SETTINGS, so Appium settings/IME fail and the session never starts. Direct uiautomator2 + OCR works (atx-agent needs no special permission). All interaction goes through the OCR loop: `ocr_bridge.py` in the appium-android-adb skill — screenshot → RapidOCR → click/swipe → re-OCR verify.\n\n## ⚠️ Critical: UC WebView Virtual List Behavior\n\nThe train list uses a **virtual list** inside the UC WebView:\n\n- Accessibility tree / DOM is mostly **collapsed** (all non-current items share y≈407 or y≈2255, h=6px) and intermittently renders. Never depend on it.\n- **OCR is the dependable eye**: RapidOCR reads Chinese out of the box (no tesseract language packs needed).\n- Raw `adb shell input tap` is **filtered** by the WebView. `d.click(x, y)` (uiautomator2) reliably delivers touches.\n- The list **skips sections** when scrolling: a departure-time window (e.g. 06:32) can be jumped over repeatedly.\n\n## New-App UI: Card Expansion + Per-Row 预订 (2026-08 version)\n\n**Collapsed train cards have NO 预订 button.** The flow is:\n\n1. Tap the **seat row** of a card (e.g. \"二等\" label area) → the card **expands** in place, showing seat rows: 二等 / 一等 / 商务 / 无座, each with price (e.g. `二等 ¥41 9折`).\n2. Each expanded row has its own **预订 button on the right edge** (on 1080px width: x≈898–980, h≈48, at the row's y).\n3. Tap that row's 预订 → 确认订单 page.\n\n```bash\n# after OCR shows target train card on screen:\n$PY ocr_bridge.py tap-text 二等                      # expand the card\n$PY ocr_bridge.py tap-text 预订 --y0 <row_top> --y1 <row_bottom>  # row's 预订\n```\n\n(Example coordinates from the real run: card row at (141, 2026) expanded; 二等 row 预订 at (939, 1987); order page followed.)\n\n## ⚠️ Departure-S"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"12306-android-adb\",\n  \"version\": \"2.2.2\",\n  \"publishedAt\": 1788078714865\n}"},{"path":"skill-card.md","content":"## Description:\n\nGuides agents through booking train tickets in the 12306 Android app over USB ADB using uiautomator2 and OCR-based verification.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgents assisting a user who explicitly asks to book a 12306 train ticket can use this skill to navigate the Android app, select trains and passengers, recover from stale ticket data, and stop before payment for user action.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill gives an agent broad ADB control over a phone already logged into 12306.\n\nMitigation: Use it only after an explicit user request, keep the confirmation step before submitting an order, and leave payment to the user on the phone.\n\nRisk: Screenshots, UI dumps, clipboard contents, and passenger details may expose sensitive data.\n\nMitigation: Avoid untrusted station or passenger text, clear the clipboard and temporary screenshot/UI files after use, and keep temporary storage private.\n\nRisk: Under-scoped helper behavior or unpinned dependencies can mishandle device commands or screen data.\n\nMitigation: Review commands before execution and pin dependencies during setup.\n\n## Reference(s):\n\n- [12306 Android Adb on ClawHub](https://clawhub.ai/openlittlebear/skills/12306-android-adb)\n- [openlittlebear publisher profile](https://clawhub.ai/user/openlittlebear)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, code, configuration]\n\n**Output Format:** [Markdown with inline bash and Python code blocks]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Directs agent behavior for Android ADB and OCR workflows; payment remains manual.]\n\n## Skill Version(s):\n\n2.2.2 (source: server release evidence)\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":"12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us... Skill: 12306 Android Adb Owner: openlittlebear Summary: 12306-specific knowledge for booking train tickets via the Android app. Covers UC WebView virtual list behavior, proven booking flow, and common pitfalls. Us... Tags: 12306:1.0.0, android:1.0.0, booking:1.0.0, latest:2.2.2, train:1.0.0 Version history: v2.2.2 | 2026-08-30T08:31:54.865Z | user skillSpector cleanup: removed unproven raw-shell patterns (adb input t","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1245,"uniquenessScore":53,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T07:07:25.836Z","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-11T07:07:25.836Z","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-11T10:51:18.444Z","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"}]}}}