Agent skill

Drive Automation Session

by jeremylongshore in jeremylongshore/tons-of-skills-marketplace

Drive an already-reserved Kobiton device from a natural-language intent.

MITAuto-check passedMobile

Install Drive Automation Session

skills CLI
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill drive-automation-session -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jeremylongshore/tons-of-skills-marketplace drive-automation-session --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/testing/kobiton-automate/skills/drive-automation-session .claude/skills/drive-automation-session && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
drive-automation-session
GitHub stars
2.8k
Token cost
~5.9k tokens
SKILL.md length
2,344 words
Files
9 (incl. scripts, references)
Skills in repo
3,342
Repo updated
First seen
Licence
MIT

At a glance

Drive an already-reserved Kobiton device from a natural-language intent.

  • The user says drive the device to X
  • SKILL.md covers Overview, Prerequisites, Step 0: Device + app selection… and Inputs, plus 5 more sections
  • Runs JavaScript scripts from its folder; calls node, bash and jq; reaches portal.kobiton.com
  • Describes a flow they want exercised on a reserved device

What it does

Drive Automation Session is an agent skill from jeremylongshore/tons-of-skills-marketplace. Drive an already-reserved Kobiton device from a natural-language intent. Opens an automation Appium session directly against the Kobiton WebDriver hub, runs an observe-decide-act loop with one action per iteration, pauses to ask the user when stuck (same-action repetition, screen unchanged, or model self-declared blocker), and returns the session id. Use when the user says "drive the device to X", describes a flow they want exercised on a reserved device, or asks to "automate this intent on Kobiton". Complements…

Its SKILL.md is about 5.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 11 other files, including scripts and reference files (for example `references/capabilities.md`, `references/endpoint-reference.md` and `references/loop-discipline.md`). Compatibility notes: Cross-platform — talks WebDriver HTTP directly via Node's built-in node:https; no platform-specific binary dependency. Requires Node.js = 18, a persistent…

It sits in Mobile, covering Mobile testing and debugging. It works with Model Context Protocol. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.

When your agent uses it

  • The user says drive the device to X
  • Describes a flow they want exercised on a reserved device
  • Asks to automate this intent on Kobiton

Example prompts

  • “drive the device to X”
  • “automate this intent on Kobiton”
  • “/drive-automation-session”

Requirements

  • Node.js
  • Compatibility (from SKILL.md): Cross-platform — talks WebDriver HTTP directly via Node's built-in node:https; no platform-specific binary dependency. Requires Node.js >= 18, a persistent local filesystem (the observe-decide-act loop passes state through local turn files), and ~/.kobiton/.credentials written by /automate:setup — scripts/appium.js reads that file directly and never calls the MCP getCredential tool, so it is required, not a fallback. An authenticated Kobiton MCP connection is additionally useful for device selection.
  • Pre-approved tools (allowed-tools): Read, Edit, Bash(node:*), Bash(bash:*), Bash(pwsh:*), Bash(mkdir:*), Bash(mv:*), Bash(date:*), Bash(echo:*), Bash(printf:*), Bash(jq:*), Bash(open:*), Bash(xdg-open:*)

What it can do on your machine

Read from SKILL.md and the folder at commit cfae287. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Edit
    • Bash(node:*)
    • Bash(bash:*)
    • Bash(pwsh:*)
    • Bash(mkdir:*)
    • Bash(mv:*)
    • Bash(date:*)
    • Bash(echo:*)
    • Bash(printf:*)

    …and 3 more on the same allowed-tools line.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 5 files in scripts/ (JavaScript), which the agent can run.

    Shell commands in SKILL.md call:

    • node
    • bash
    • jq
    • claude
    • pwsh

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • portal.kobiton.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Cross-platform — talks WebDriver HTTP directly via Node's built-in node:https; no platform-specific binary dependency. Requires Node.js >= 18, a persistent local filesystem (the observe-decide-act loop passes state through local turn files), and ~/.kobiton/.credentials written by /automate:setup — scripts/appium.js reads that file directly and never calls the MCP getCredential tool, so it is required, not a fallback. An authenticated Kobiton MCP connection is additionally useful for device selection.

    From compatibility in the SKILL.md frontmatter.

Context cost

Drive Automation Session loads about 5.9k tokens when it runs, and up to ~17k if it reads all its reference files. Until then it costs about 184 tokens; SKILL.md has 2,344 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~184
When it runs · the whole SKILL.md, loaded when a task matches
~5.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~17k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from jeremylongshore/tons-of-skills-marketplace at commit cfae287, republished under its MIT licence (© jeremylongshore). 2,344 words, ~5,942 tokens.

Download SKILL.mdSave it as .claude/skills/drive-automation-session/SKILL.md (or your agent's skills folder). This skill also uses 8 other files; get the full folder from GitHub.
name
drive-automation-session
description
Drive an already-reserved Kobiton device from a natural-language intent. Opens an automation Appium session directly against the Kobiton WebDriver hub, runs an observe-decide-act loop with one action per iteration, pauses to ask the user when stuck (same-action repetition, screen unchanged, or model self-declared blocker), and returns the session id. Use when the user says "drive the device to X", describes a flow they want exercised on a reserved device, or asks to "automate this intent on Kobiton". Complements run-interactive-session (which uses the CLI session type) by using the automation session type so the resulting session is consumable by saveTestCase and the existing test-run authoring flow.
allowed-tools
Read, Edit, Bash(node:*), Bash(bash:*), Bash(pwsh:*), Bash(mkdir:*), Bash(mv:*), Bash(date:*), Bash(echo:*), Bash(printf:*), Bash(jq:*), Bash(open:*), Bash(xdg-open:*)
compatibility
Cross-platform — talks WebDriver HTTP directly via Node's built-in node:https; no platform-specific binary dependency. Requires Node.js >= 18, a persistent local filesystem (the observe-decide-act loop passes state through local turn files), and ~/.kobiton/.credentials written by /automate:setup — scripts/appium.js reads that file directly and never calls the MCP getCredential tool, so it is required, not a fallback. An authenticated Kobiton MCP connection is additionally useful for device selection.
version
1.0.0
author
Kobiton Inc.
license
MIT
tags
mobile, testing, appium, natural-language, intent, automation, kobiton

Drive from Intent

Overview

Drive a Kobiton device from a natural-language intent. The caller provides:

  1. An intent string (e.g. "open Settings, enable Bluetooth, then go back to home").
  2. A UDID for a device the caller has already reserved.
  3. An app reference (kobiton-store:vXXXXX) or a browser name for web sessions.

The skill opens an automation-type Appium session (with appium:newCommandTimeout: 1800 so the session survives pauses while the model asks for guidance), runs an observe-decide-act loop, and returns the session id. The returned session is consumable by the Kobiton MCP tools getSession, getSessionArtifacts, and saveTestCase exactly like any other automation session.

Tool naming. This doc refers to Kobiton MCP tools by their bare names (getSession, reserveDevice, terminateSession, …). The exact registered name depends on how the host loaded the MCP server (e.g. Claude Code as a plugin exposes mcp__plugin_automate_kobiton__getSession; a repo-local .mcp.json or claude mcp add exposes mcp__kobiton__getSession; other hosts differ). Models fuzzy-match on the bare name, so use it and let the host resolve the prefix.

This skill complements — and does NOT replace — run-interactive-session. They serve different session types:

SkillSession typeBest for
run-interactive-sessionCLI session (~/.kobiton/bin/kobiton)Human-driven exploration, ad-hoc inspection
drive-automation-sessionAutomation session (direct Appium HTTP)AI-driven flows, saveable as a test case

Prerequisites

Runs on any OS, but needs two things from the host: a persistent local filesystem — the observe-decide-act loop passes state between turns through iter-N.*.json files, so that file handoff is the loop — and ~/.kobiton/.credentials, which scripts/appium.js reads directly (see below). A host with a filesystem but no way to run /automate:setup still can't finish; route those users to create-test-run. Node.js 18+; no native binary (scripts/appium.js uses node:https). See the Skill compatibility matrix in CLAUDE.md.

  • Credentials available. scripts/appium.js reads ~/.kobiton/.credentials (written by /automate:setup) directly on every invocation and stops with no-credentials if it's missing — this file is required, not a fallback, and the script never calls the MCP getCredential tool. Reading it directly is deliberate: credentials never pass through argv, env, or the host transcript.
  • A device. Either the user provides one (UDID, deviceName, platformVersion) or the skill helps pick + reserve one (see Step 0 below).
  • An app (for app testing) — a Kobiton-store reference like kobiton-store:vXXXXX, an .apk / .ipa to upload, or a browser name (for web testing). The skill helps locate or upload it in Step 0.

Step 0: Device + app selection (ask before picking)

Before reserving anything, the skill clarifies what the user wants. Do NOT auto-pick a device unless the user's intent unambiguously implies a platform AND the user did not constrain the choice.

Device

If the user didn't specify a device in their intent:

  1. Ask: "Which device or platform? (e.g., 'a Pixel running Android 14', 'an iPhone 15 Pro', or pick any available Android)." Wait for the response.
  2. If they name a class (e.g., "any Pixel", "any iOS phone"), call listDevices with the relevant platform filter and present the top 3-5 options with name + OS version + availability.
  3. If they name a specific device, verify availability via getDeviceStatus before reserving.
  4. Reserve via reserveDevice. Capture the UDID, deviceName, platformVersion, automationName for Step 2's caps render.

If the user's intent strongly implies a platform (e.g., "test the iOS App Store flow", "open Chrome on Android"), it's OK to auto-pick — but state which device you're picking and why in one line before reserving, so the user can redirect.

App

For an app testing session:

  • If the user referenced a build (@build.apk, "the latest staging build", kobiton-store:vXXXXX), use it. Verify the store reference exists via listApps if uncertain.
  • If they didn't reference one, ask: "Which app should the session install? (path to a local .apk/.ipa, an existing kobiton-store:vXXXXX reference, or none if the intent is browser-only)."
  • Upload local files via uploadAppToStore → confirmAppUpload → poll getAppParsingStatus until the state is terminal (OK = ready; stop on a FAILURE_* value). confirmAppUpload only kicks off async parsing on the backend — it does NOT guarantee the app is ready, so the session can fail to install if you skip the poll.

For a web testing session, skip the app step — --testingType web --browserName chrome|safari is enough.

Live view

If the user didn't say how they want to observe the session, ask before creating it:

"Open the device live view to watch the agent drive (foreground), or run the session in the background?"

Two options:

  • Open in foreground — after the session is created, build the device-only URL <portal>/devices/launch?id=<deviceId>&view=device-only (same shape as run-automation-suite Step 5; the <deviceId> is the one captured during Step 0 reservation) and launch it via the chromeless launcher chain (see Step 3b for the chromeless-vs-default-browser branching). The URL is also surfaced as text so the user can click manually if the launcher can't open Chrome and no default-browser fallback applies.
  • Run in background — proceed straight to the loop. The user can still inspect artifacts (XML/PNG/video) after the cycle ends.

Remember the choice; act on it in Step 3 right after the session is created. Do NOT auto-open without asking — some users prefer silent runs, especially on shared screens.

Inputs

InputRequiredNotes
intentyesOne to a few sentences describing what the user wants done on the device
udidyesThe device the caller has reserved
platformNameyesAndroid or iOS (look up via getDeviceStatus if unknown)
platformVersionyesfrom getDeviceStatus
deviceNameyesfrom getDeviceStatus
automationNamerecommendedUiAutomator2 (Android) or XCUITest (iOS)
app OR browserNameyeskobiton-store:vXXXXX for app testing, browser name for web testing
testingTypenoapp (default) or web
MAX_ITERSnoenv var override; default 100. Hard ceiling on iteration count — pure safety net against runaway cycles, not a stuck-detection mechanism.

Steps

1. Verify credentials are available

appium.js reads ~/.kobiton/.credentials directly on every invocation. If the file is missing, tell the user to run /automate:setup and stop:

bash
if [ ! -s ~/.kobiton/.credentials ]; then
  echo "Credentials not found. Run /automate:setup first." >&2
  exit 1
fi
2. Render desired capabilities

Reuse run-automation-suite's renderer. The --newCommandTimeout 1800 flag is the key piece for this skill.

bash
SKILL_DIR=$(dirname "$0")   # this skill's directory
RENDER=$(realpath "$SKILL_DIR/../run-automation-suite/scripts/render-capabilities.js")

# Unique temp file — two concurrent sessions (two terminals / conversations)
# must not clobber each other's rendered caps before Step 3 reads them.
CAPS_TMP=$(mktemp "${TMPDIR:-/tmp}/drive-automation-session-caps.XXXXXX.json")

node "$RENDER" \
  --platformName "$PLATFORM_NAME" \
  --udid "$UDID" \
  --deviceName "$DEVICE_NAME" \
  --platformVersion "$PLATFORM_VERSION" \
  --automationName "$AUTOMATION_NAME" \
  --app "$APP" \
  --testingType "${TESTING_TYPE:-app}" \
  --newCommandTimeout 1800 \
  --scriptlessCapture \
  > "$CAPS_TMP"

appium.js reads ~/.kobiton/.credentials on each invocation. No flags, no env vars.

3. Create the session
bash
SESSION_ID=$(node "$SKILL_DIR/scripts/appium.js" \
  --method POST --url /session \
  --req-body "@$CAPS_TMP" \
  | jq -r '.value.sessionId // .sessionId')

SESSION_DIR=".kobiton/sessions/$SESSION_ID"
mkdir -p "$SESSION_DIR"
mv "$CAPS_TMP" "$SESSION_DIR/caps.json"
printf '%s session=%s started intent=%q\n' "$(date -u +%FT%TZ)" "$SESSION_ID" "$INTENT" > "$SESSION_DIR/session.log"

trap 'cleanup' EXIT INT TERM
cleanup() {
  [ -z "$SESSION_ID" ] && return 0
  # DELETE /wd/hub/session/<id> ends the WebDriver session cleanly; Kobiton
  # records state=COMPLETE. appium.js already treats 404 as idempotent success
  # (the session was already gone). appium.js always exits 0 by policy, so we
  # check stderr instead of $? to detect a real failure.
  delete_err=$(node "$SKILL_DIR/scripts/appium.js" \
    --method DELETE --url "/session/$SESSION_ID" 2>&1 >/dev/null)
  if [ -z "$delete_err" ]; then
    printf '%s session=%s end-via-trap status=COMPLETE\n' "$(date -u +%FT%TZ)" "$SESSION_ID" >> "$SESSION_DIR/session.log"
  else
    printf '%s session=%s end-via-trap delete-failed (session will time out per appium:newCommandTimeout) err=%s\n' "$(date -u +%FT%TZ)" "$SESSION_ID" "$delete_err" >> "$SESSION_DIR/session.log"
  fi
}
3b. Act on the live-view choice from Step 0

Build the device-only URL from the device id captured during Step 0 reservation and the portal base URL (e.g., https://portal.kobiton.com) — the AI host has the portal value from earlier MCP responses in the conversation context. Same URL shape as run-automation-suite Step 5.

bash
LIVE_VIEW_URL="<portal>/devices/launch?id=<deviceId>&view=device-only"
printf 'Live view: %s\n' "$LIVE_VIEW_URL"

(The post-run replay URL is <portal>/sessions/<kobiton-session-id>/explorer — a different page, NOT the live view. Surface that one only after the session completes if the user wants to review the recording.)

If the user chose background in Step 0, stop here — the URL is logged and the loop proceeds. They can paste it into a browser later if they get curious.

If the user chose foreground, reuse run-automation-suite's launcher chain instead of re-implementing it. The pattern (chromeless Chrome for users who haven't expressed a preference or prefer Chrome; default-browser fallback otherwise) is identical to run-automation-suite Step 5.

Launch via the chromeless helper (default — gated on saved browser preference). Check auto memory for a saved browser preference:

  • No preference saved, OR preference is Google Chrome → invoke the chromeless launcher below.
  • Preference is Safari, Firefox, or Default browser → skip the launcher; go straight to the default-browser fallback table.

Pick width and height from the reserved device's form factor (the device name from Step 0):

Device classDetect by name (case-insensitive)Portrait W × HLandscape W × H
TabletiPad, Galaxy Tab, Pixel Tablet, Surface, MatePad, or any model with Tab / Pad780 × 920920 × 780
Fold (unfolded)Fold, Z Fold, Pixel Fold880 × 920920 × 880
Phone (default)none of the above540 × 920920 × 540

Swap width and height if getSession / rendered caps report orientation=LANDSCAPE — default is portrait.

Invoke per host OS. Run in the background (Claude Code: Bash tool with run_in_background: true; other hosts: append & and disown) so the resize-polling loop doesn't block iteration 1. The launcher's stdout/stderr will surface later when it completes; the URL printed above is the user's fallback if the launcher silently fails.

OSCommand
macOSbash $SKILL_DIR/../run-automation-suite/scripts/chromeless-launcher.sh --url "$LIVE_VIEW_URL" --width <W> --height <H>
Windowspwsh $SKILL_DIR/../run-automation-suite/scripts/chromeless-launcher-windows.ps1 -Url "$LIVE_VIEW_URL" -Width <W> -Height <H>
Linuxbash $SKILL_DIR/../run-automation-suite/scripts/chromeless-launcher.sh --url "$LIVE_VIEW_URL" --width <W> --height <H> (launch-only on Linux — no auto-resize)

Launcher exit codes (surface in the background-task completion event):

  • 0 — Chrome was launched (resize may or may not have succeeded; the warning is informational).
  • 2 — Chrome / Chromium is not installed. The user already has $LIVE_VIEW_URL from the printf above; they can paste it into their default browser, or you can offer the default-browser fallback table below as a follow-up.
  • 64 — usage error in the launcher invocation. Surface to the user.

Default-browser fallback (when the saved preference is Safari/Firefox/Default, or chromeless exited 2). Ask the user once which browser to use (save to auto memory):

ChoiceCommand
Google Chromeopen -na "Google Chrome" --args --new-window "$LIVE_VIEW_URL"
Safariopen -a "Safari" "$LIVE_VIEW_URL"
Firefoxopen -a "Firefox" "$LIVE_VIEW_URL"
Default browseropen "$LIVE_VIEW_URL"

On Linux, fall back to xdg-open "$LIVE_VIEW_URL" (browser selection isn't supported).

If neither path is available, the URL is already on stdout from the printf above — the user can copy-paste it.

Show full SKILL.md (848 more words)Show less
4. Per-turn iteration pattern (three branches)

There is no Bash while. The skill is turn-based: each turn, you (the AI host) increment ITER and pick exactly one of three branches:

BranchCommandWhen to pick
screennode appium.js screen --session-id $SID --session-dir $DIRThe screen state has likely changed (after a successful act, or at session start, or to verify mid-flow).
actnode appium.js <argv> --session-dir $DIRYou know what to do based on the most recent iter-K.xml you observed.
controlnode appium.js control --done|--blocked --reason "..." --session-dir $DIRGoal reached, or you're genuinely stuck. Ends the cycle.

Each branch consumes one ITER. The script always exits 0; the host detects failures by checking whether iter-N.error.json was written.

bash
export ITER=$((ITER + 1))

# Pick ONE of the three. Credentials inherit from env (Step 1).

# Branch A: observe — captures BOTH iter-N.xml and iter-N.png by default.
#   Native overlays / OS dialogs only show in the PNG (the webview source
#   XML doesn't see them). --xml-only skips the screenshot to save tokens
#   when you trust the XML is complete; --png-only skips the source when
#   you're verifying layout / image rendering only.
node "$SKILL_DIR/scripts/appium.js" screen \
  --session-id "$SESSION_ID" --session-dir "$SESSION_DIR"
# Stdout: {"hash":"<sha256>","xmlBytes":N,"pngBytes":M}
# Track the hash across turns in your conversation context — repetition is a
# signal, never a forced stop. See references/loop-discipline.md "Stuck patterns".

# Branch B: act — execute an Appium call. Writes iter-N.request.json + either
#   iter-N.response.json (success) or iter-N.error.json (any failure). The
#   error file contains the raw Appium body or {error, message} for usage
#   errors; the host reads it to decide what to do next turn.
node "$SKILL_DIR/scripts/appium.js" <YOUR-ARGV> --session-dir "$SESSION_DIR"
# Examples of <YOUR-ARGV>:
#   --method POST --url /session/$SESSION_ID/element --req-body '{"using":"xpath","value":"//Button"}'
#   actions --session-id $SESSION_ID --type swipe --from-x 540 --from-y 1800 --to-x 540 --to-y 600
#   touch-perform --session-id $SESSION_ID --steps @/tmp/steps.json
#   --method POST --url /session/$SESSION_ID/element/$EL_ID/clear --req-body '{}'

# Branch C: end the cycle.
node "$SKILL_DIR/scripts/appium.js" control \
  --done --reason "Settings reached and Bluetooth toggled" \
  --session-dir "$SESSION_DIR"
# OR --blocked --reason "Two modals stacked; cannot dismiss"

# ---- Per-turn bookkeeping (runs after the chosen branch) ----

# Log failures so session.log has a timeline. appium.js writes iter-N.error.json
# on any failure — Appium HTTP error, network blip, usage error like missing
# flag or malformed JSON. The host reads the file next turn and re-plans.
ITER_PAD=$(printf '%03d' "$ITER")
if [ -f "$SESSION_DIR/iter-$ITER_PAD.error.json" ]; then
  printf 'iter=%d error\n' "$ITER" >> "$SESSION_DIR/session.log"
fi

# Iteration ceiling — safety net only. Not a stuck-detection mechanism.
if [ "$ITER" -ge "${MAX_ITERS:-100}" ]; then
  printf 'iter=%d max-iters-reached limit=%d\n' "$ITER" "${MAX_ITERS:-100}" >> "$SESSION_DIR/session.log"
  exit 0
fi
Branch decision guide

What to pick next turn depends on what just happened:

  • Successful act → next turn screen (the screen probably changed).
  • screen just ran → next turn act (you have a fresh observation).
  • act returned no such element / invalid selector / bad-input → next turn act again with a corrected call. The screen didn't change (the action didn't fire), so the most recent iter-K.xml is still valid; re-read it from disk if you need to, but don't burn an ITER on a fresh screen.
  • act returned stale element reference → next turn screen (the element id is from a prior state; you need a fresh observation to get current element ids).
  • act returned HTTP 5xx / network timeout → next turn act again with the same call (retry). If it fails twice, control --blocked.
  • Goal reached → control --done.
  • Genuinely stuck (per the patterns in loop-discipline.md "Stuck patterns") → control --blocked.

The host is responsible for tracking which iter-K.xml represents the current screen state. After a successful act, the previous iter-K.xml is stale until the next screen. After a failed act, the previous iter-K.xml is still current.

Building act calls from the XML

When the chosen branch is act, the argv body is constructed from the most recent iter-K.xml — selectors come from attributes you can see in the XML, not from guesses. See references/endpoint-reference.md "Building Appium calls from the observed XML" for the find-element → element-id workflow, selector-strategy preference order (accessibility id > id > relative xpath > css selector > class name), and the coordinates-from-bounds fallback for gestures with no element target.

The full loop discipline (artifact paths, error feedback, termination conditions) lives in references/loop-discipline.md. The endpoint catalog (allowlisted vs not, helpers vs generic) lives in references/endpoint-reference.md.

5. Cleanup

The Bash trap (set up in Step 3) issues DELETE /wd/hub/session/$SESSION_ID on exit (loop end, error, user stop). That's the clean way to end the session — Kobiton records the session state as COMPLETE, which is what saveTestCase and analytics expect.

Do NOT call the terminateSession MCP tool here. It ends the session via Kobiton's platform-side kill path, which marks the session state as TERMINATED — distinct from COMPLETE and treated as an abnormal exit by the recording pipeline. Reserve terminateSession for the genuinely-stuck case where the WebDriver DELETE is unreachable (network down, Appium hub unresponsive) AND the user explicitly asks to force-kill the session.

If the DELETE somehow fails silently, the session will time out on the Kobiton side per appium:newCommandTimeout (30 min, set in Step 2). Better to wait for that timeout than to mark the session TERMINATED.

6. Return

Emit the session id back to the caller. The session is now consumable by:

  • getSession({sessionId}) — session metadata, device info, results.
  • getSessionArtifacts({sessionId}) — video, logs, screenshots, reports.
  • saveTestCase({sessionId}) — persist as a re-runnable test case (sibling feature, out of scope here).

Endpoint reference

See references/endpoint-reference.md for the full Appium endpoint catalog — allowlisted (capturable by saveTestCase) vs not, helpers (actions, touch-perform) vs generic mode. The AI host picks endpoints from that table when emitting iter-N.call.json.

Stuck patterns — host decides when to pause

The script does not enforce blocker thresholds. The AI host tracks the hash from screen across turns in its conversation context and decides when to emit control --blocked. See references/loop-discipline.md "Stuck patterns" for concrete examples — same-call repetition, screen oscillation (A→B→A→B), credentials prompt, CAPTCHA, lazy load (use a no-op observe to wait), network spinner.

The only hard programmatic stop is MAX_ITERS=100 (override per session), which is a safety net against runaway cycles — not a stuck-detection mechanism.

Errors

SymptomLikely causeFix
No credentials available...No ~/.kobiton/.credentials (an authenticated MCP connection does not substitute — appium.js only reads the file)Run /automate:setup, which uses the MCP connection to fetch and write the file
iter-N.error.json has status: 401 on session createCredentials staleRe-run /automate:setup to refresh ~/.kobiton/.credentials; check the portal URL
iter-N.error.json has a platform-cap message on session createnewCommandTimeout: 1800 rejected by KobitonLower the timeout in references/capabilities.md
iter-N.error.json body has value.error: "no such element"Selector matched nothingRe-plan next turn with a different strategy / selector
iter-N.error.json body has value.error: "invalid session id"Kobiton platform-side session endedEmit control --blocked (or just let MAX_ITERS catch it); trap cleans up

Notes

  • The kobiton:aiToolName capability is auto-detected by render-capabilities.js (Claude / Codex / Copilot / Gemini). No flag needed.
  • Artifacts live under .kobiton/sessions/<session-id>/ — workspace-relative, not /tmp (consistent with run-interactive-session).
  • The skill writes nothing to tools/*.yaml and does not add any MCP tool. It only consumes existing MCP tools (reserveDevice, getSession, terminateSession, etc.).

© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 8 other files (scripts, references) in plugins/testing/kobiton-automate/skills/drive-automation-session of jeremylongshore/tons-of-skills-marketplace.

  • SKILL.md
  • references/capabilities.md
  • references/endpoint-reference.md
  • references/loop-discipline.md
  • scripts/__fixtures__/webview-mobile-sample.xml
  • scripts/appium.js
  • scripts/appium.test.js
  • scripts/strip-webview-dom.js
  • scripts/strip-webview-dom.test.js

Open the folder on GitHubat commit cfae287

Compare with similar skills

Drive Automation Session next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Drive Automation Session compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Drive Automation Session this skilljeremylongshore/tons-of-skills-marketplace2.8k—~5.9kAutomated safety check: PassMIT
BrowserStack Live Testinghandsontable/handsontable22k—~950Automated safety check: PassCustom licence
Magicnet Device DebuggingLIghtJUNction/MagicNet186—~2.9kAutomated safety check: NotesMIT
Scrcpy GotchasJuanCF/scrcpy-mcp116—~5.8kAutomated safety check: PassMIT
iOS Accessibility Testingconorluddy/xclaude-plugin183—~5kAutomated safety check: PassMIT
Generate Appclaw Flowappclawhq/AppClaw117—~3.4kAutomated safety check: NotesApache-2.0

Similar skills

  • BrowserStack Live Testing

    handsontable/handsontable

    Opens a live BrowserStack session on a real Android, iOS or desktop browser for a local or public URL, tunneling localhost through Cloudflare when needed.

    22k GitHub stars~950 tokensUpdated yesterday
    Testing & QAAuto-check passed
  • Magicnet Device Debugging

    LIghtJUNction/MagicNet

    Debug and verify MagicNet on a real Android root device. An agent skill from LIghtJUNction/MagicNet.

    186 GitHub stars~2.9k tokensUpdated today
    MobileAuto-check: notes
  • Scrcpy Gotchas

    JuanCF/scrcpy-mcp

    A skill your agent uses when interacting with Android devices via scrcpy-mcp tools (tap, swipe, inputtext, keyevent, uidump, uifindelement, appstart, etc.).

    116 GitHub stars~5.8k tokensUpdated 18 days ago
    MobileAuto-check passed
  • iOS Accessibility Testing

    conorluddy/xclaude-plugin

    Guides WCAG 2.1 and VoiceOver accessibility testing for iOS apps, working from the accessibility tree and not from screenshots.

    183 GitHub stars~5k tokensUpdated 29 days ago
    Testing & QAAuto-check passed
  • Generate Appclaw Flow

    appclawhq/AppClaw

    Generate YAML flow files for AppClaw mobile automation. An agent skill from appclawhq/AppClaw.

    117 GitHub stars~3.4k tokensUpdated 1 mo ago
    MobileAuto-check: notes
  • Spock Adb

    WahdanZ/SpockAdb

    Debug Android apps on a connected device or emulator through the Spock ADB MCP server (tools named android).

    116 GitHub stars~3.8k tokensUpdated today
    MobileAuto-check passed

More from jeremylongshore/tons-of-skills-marketplace

All 3,342 skills in this repo
  • Performing Security Code Review

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.

    2.8k GitHub starsUsed in 2 repos~1.3k tokens
    Auto-check: notes
  • Adapting Transfer Learning Models

    jeremylongshore/tons-of-skills-marketplace

    Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Agent Context Loader

    jeremylongshore/tons-of-skills-marketplace

    Execute proactive auto-loading: automatically detects and loads agents.md files.

    2.8k GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Aggregating Performance Metrics

    jeremylongshore/tons-of-skills-marketplace

    Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.

    2.8k GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Analyzing Capacity Planning

    jeremylongshore/tons-of-skills-marketplace

    Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.

    2.8k GitHub stars~947 tokensUpdated today
    Auto-check passed
  • Analyzing Database Indexes

    jeremylongshore/tons-of-skills-marketplace

    Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.

    2.8k GitHub stars~2k tokensUpdated today
    Auto-check passed

Categories

Questions about Drive Automation Session

What does Drive Automation Session do?

Drive an already-reserved Kobiton device from a natural-language intent. Drive Automation Session is an agent skill from jeremylongshore/tons-of-skills-marketplace. Drive an already-reserved Kobiton device from a natural-language intent.

When should I use Drive Automation Session?

Drive Automation Session fits situations like: the user says drive the device to X; describes a flow they want exercised on a reserved device; asks to automate this intent on Kobiton.

How do I install Drive Automation Session in Claude Code?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill drive-automation-session -a claude-code`. Or copy the skill folder (plugins/testing/kobiton-automate/skills/drive-automation-session in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/drive-automation-session in your project. Claude Code loads it when a task matches its description.

How do I install Drive Automation Session in Codex?

Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill drive-automation-session -a codex`. Or copy the skill folder (plugins/testing/kobiton-automate/skills/drive-automation-session in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/drive-automation-session in your project. Codex loads it when a task matches its description.

Can I use Drive Automation Session in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill drive-automation-session -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/drive-automation-session, .gemini/skills/drive-automation-session, .github/skills/drive-automation-session and .opencode/skills/drive-automation-session in your project.

What does Drive Automation Session need to run?

Going by SKILL.md and its folder, Drive Automation Session needs JavaScript for the scripts in its folder and the command-line tools its instructions call (node, bash, jq, claude and pwsh). Our summary lists: Node.js. Its frontmatter pre-approves these tools: Read, Edit, Bash(node:*), Bash(bash:*), Bash(pwsh:*), Bash(mkdir:*), Bash(mv:*), Bash(date:*), Bash(echo:*), Bash(printf:*), Bash(jq:*), Bash(open:*), Bash(xdg-open:*). Compatibility (from SKILL.md): Cross-platform — talks WebDriver HTTP directly via Node's built-in node:https; no platform-specific binary dependency. Requires Node.js >= 18, a persistent local filesystem (the observe-decide-act loop passes state through local turn files), and ~/.kobiton/.credentials written by /automate:setup — scripts/appium.js reads that file directly and never calls the MCP getCredential tool, so it is required, not a fallback. An authenticated Kobiton MCP connection is additionally useful for device selection..

Does Drive Automation Session access the network?

SKILL.md names 1 domain. In commands or code: portal.kobiton.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Drive Automation Session safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Drive Automation Session use?

Drive Automation Session is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Drive Automation Session use?

About 5.9k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 11k tokens, read only when the agent opens those files.

What are the alternatives to Drive Automation Session?

Skills that share tags, products or a category with Drive Automation Session: BrowserStack Live Testing (handsontable/handsontable, 22k stars), Magicnet Device Debugging (LIghtJUNction/MagicNet, 186 stars), Scrcpy Gotchas (JuanCF/scrcpy-mcp, 116 stars) and iOS Accessibility Testing (conorluddy/xclaude-plugin, 183 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Drive Automation Session?

jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,827 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 10, 2026.

Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.