Use the directory containing this file as the Skill root directory. Use only the Skill's thin entry point:
scripts/solopi-ai --pretty <命令>
At execution time, resolve scripts/solopi-ai to an absolute path, and keep the caller's current working directory unchanged. The Harness implementation and built-in templates are placed with this Skill in scripts/harness/. The entry point by default calls only this implementation and does not depend on sibling directories outside the repository or installed Python packages. When the caller explicitly configures SOLOPI_HARNESS_CLI , another exact CLI can be specified; ordinary use requires no configuration. Do not assemble HTTP, Scheme, or Shell commands yourself in place of the typed CLI.
During installation, copy this Skill directory in full and preserve script execution permissions; running requires Python 3.9+ and the ADB needed for device operations. Laya weights, virtual environments, APKs, and real-device evidence are not packaged with the Skill. For standalone installation and local verification, seeBuilt-in Workflows。
Global parameters must be placed before the subcommand. When multiple devices are online, every invocation must add --serial <adb-serial>。
Quick Start
When the user wants to "connect a phone and run a few cases," "run the Alipay template," or "view results with screenshots," read Built-in Workflowsfirst, and use the following entry point:
scripts/solopi-ai --pretty workflow-list
scripts/solopi-ai --serial <adb-serial> --pretty workflow-run --template alipay-more-services
scripts/solopi-ai --pretty workflow-report --artifacts <上一步返回的artifacts>
The default rule mode does not load a model. Only when the user explicitly selects the Laya experiment should you pass --mode laya --model <本地MLX权重目录>;
the model runs on the computer. Do not install a companion APK for these templates, and do not treat model output as an acceptance conclusion.
workflow-run automatically completes pre-checks, plan compilation and validation, execution, and the screenshot report; when the prerequisite page is not satisfied, it retains not_tested,
and does not automatically rerun. After completion, return the Markdown report path and explain the three-state result, cleanup result, and whether screenshots are complete.
Capability Routing
When you need to determine whether a certain App capability is a direct CLI, indirect via test cases, user interaction, or not yet safely automatable, first read Capability Matrix. When you need to prove whether pages, settings, and actions have been included in coverage, then read App Feature Coverage Checklist。
| User Intent | Command to Use | Must Read |
|---|---|---|
| Select a built-in template, execute with one command, and view a full-screen screenshot report | workflow-list、workflow-run、workflow-report |
Built-in Workflows |
| Check devices, restore internal ADB, and query version and protocol | doctor、adb-connect、capabilities、app-info、app-status |
Troubleshooting |
| Discover the application under test and actions | apps、actions |
CLI Reference、Action Catalog |
| Query or modify configuration | config-list、config-get、config-set |
CLI Reference、Protocol |
| Start, observe, or stop interaction recording | record-start、record-status、record-stop |
CLI Reference、Troubleshooting |
| Query, export, or delete test cases | cases、case-get、case-delete |
CLI Reference |
| Create, validate, or import test cases | case-template、case-validate、case-import |
Test Case Authoring、Action Catalog |
| View or edit the steps of an exported test case | case-step-list、case-step-add、case-step-update、case-step-delete、case-step-move、case-step-copy |
Test Case Authoring、Action Catalog |
| Get the current page and real selector | inspect |
Test case authoring |
| Single synchronous or asynchronous replay | run、status、result、cancel |
Protocol、CLI reference |
| Dynamic Agent observation, typed actions, pause and cleanup | agent-session-start、agent-observe、agent-act、agent-status、agent-timeline、agent-pause/resume/end/cancel |
Protocol、CLI reference |
| Compile and execute reproducible verification from requirements/AC | verify-normalize、verify-compile、verify-validate、verify-run |
Verification engineering、CLI reference |
| Persistent device pool, task queue, matrix scheduling, and CI/API hosted execution | managed-* |
Hosted execution and device pool、Protocol |
| Signed on-device model installation, activation, rollback, inference, benchmarking, and release gating | model-*、verify-run --decision-provider |
On-device Agent model deployment、Verification engineering |
| Repeated or batch replay | run-repeat、run-batch |
CLI reference、Protocol |
| List, detail, and delete of replay history | replay-history-list、replay-history-get、replay-history-delete |
CLI reference、Protocol |
| Performance metrics, real-time monitoring, and collection sessions | perf-list、perf-current、perf-display-start/status/stop、perf-start/status/stop |
Performance testing |
| Descriptive statistics of local performance CSV | perf-analyze |
Performance testing |
| Android app cold start or warm start duration | startup-time |
Performance testing、CLI reference |
| List, detail, and delete of performance history | perf-history-list、perf-history-get、perf-history-delete |
Performance testing、Protocol |
| CPU or memory stress testing | stress-start、stress-status、stress-stop |
Performance testing、Troubleshooting |
| Standalone screen recording sessions and MP4 evidence | screen-record-start、screen-record-status、screen-record-stop |
CLI reference、Troubleshooting |
| Camera barcode scanning sessions and read-only content | scan-start、scan-status、scan-cancel |
CLI reference、Protocol、Troubleshooting |
| Screen recording video differential visual response latency | video-analysis-start、video-analysis-status |
Performance testing、CLI reference |
| Plugin listing, local installation, and precise removal | plugin-list、plugin-install、plugin-remove |
CLI reference、Troubleshooting |
| Standalone capture of screenshots or logs | screenshot、logs |
CLI reference |
workflow-list、workflow-report、actions、case-template、case-validate、case-step-*、perf-analyze、verify-normalize、verify-compile and verify-validate are purely local operations.workflow-run Built-in doctor;verify-run Before the first execution of other SoloPi protocol device operations, run doctor;startup-time、screenshot and logs only require an ADB device, and do not require the SoloPi control protocol or internal permissions to be ready.
General execution rules
- Device commands first run
doctor; the purely localactions、case-template、case-validate、case-step-*andperf-analyzedo not connect to a device and can be executed directly.doctorCheck permissions according to the execution mode declared by the device: supportexecutionProfiles.hostPC-side replay only requires internal ADB and accessibility; the battery optimization whitelist is only a suggestion, floating windows do not block execution,backgroundis still only a prompt-type status. Older APK versions retain the original gating and prompt an upgrade. Phone interaction recording and floating window features check permissions on demand through their corresponding entry points. If the only missing item is internaladb, useadb-connectto initiate SoloPi's own connection and wait for the exactrequestIdterminal state, then use the completedoctoris the access control. When other missing items exist, stop device changes and report; do not silently authorize. - Run
capabilities, and only call SoloPi protocol commands that the device declares it supports;startup-timeis a fixed ADB capability built into the current Skill CLI and is not part of the device control protocol. - Query real data: for applications use
apps, for built-in action contracts useactions, for test cases usecases, for performance metrics useperf-list。actionsdoes not access the device, and will not discover entry points or Providers additionally registered by plugins; do not guess package names, actions, test case names, or metric keys. - Save the
requestIdused for each change and replay start, as well as the replay'srunId, thesessionIdfor performance/recording/stress/standalone screen recording operations, the opaqueidof history records, and the plugin's stablepluginId. Subsequent queries, stops, or deletions must use the original identifier; when identifiers do not match, stop attribution. - Only when the corresponding state machine's successful terminal state and exit code both meet the requirements may completion be reported. ADB having accepted, the request having been received, or the session still being active are not business success.
- After a timeout or interruption, first query the status corresponding to the exact identifier, then stop the active sessions belonging to this task; do not start new sessions of the same kind before cleanup is confirmed complete.
SoloPi device state changes are sent via an explicit ADB Activity protected by android.permission.DUMP ; ordinary apps, web deep links, and HTTP after ADB forwarding cannot enter this change channel. HTTP is only used for queries.adb-connect only calls SoloPi's existing internal connection flow, does not accept RSA pop-ups, does not modify internal addresses, and does not execute adb tcpip 5555。startup-time only allows internally fixed Launcher resolution and am start -W commands. The CLI does not provide backdoors for arbitrary Shell, arbitrary Scheme, arbitrary HTTP, or direct Wi-Fi connection to device ports.
Dynamic Agent
For dynamic tasks, first execute agent-session-start and save the sessionId、ownerToken and first-frame observationIdfrom the output. At each step, select the target only from the real nodeId of that observation, and call stepId with a new agent-act; the next step uses the new observation after settle in the receipt, or explicitly executes agent-observe. Upon receiving stale_observation , you must re-observe and re-decide; do not blindly replay old nodes or old actions.
Only use the click、longClick、input、back、home、scroll、waitpublished by the CLI. The dynamic protocol does not accept arbitrary Shell, Provider, enum names, data clearing, or process control. On normal completion, execute agent-endwith the original identity; on abandonment or error paths, execute agent-cancel; during pause, observe and query are allowed, but act is not. Finally use agent-timeline to verify each input observation, typed action, receipt, settled observation, terminal state, and lease release event.
AI Verification Engineering
When handing requirements/AC to verification engineering, you must first readVerification Engineering Contract. Stable steps must be declared as operation and compiled into fixed SoloPi test cases; only work whose selectors or paths are unknown is declared as a budgeted explore. Model output done only stops exploration; it cannot write checkpoint state or final results.
Before execution, it must pass verify-validate. JSON field oracle is the deterministic expected rule for checkpoints;
Result Judge is the sole final adjudicating entity. Only when all required checkpoints in the unified report have evidence from this run
and the oracle rules pass and required cleanup also succeeds can the whole be reported passed;failed and
not_tested must not be merged. Reproducibility comparison uses planFingerprint + outcomeFingerprint, and does not compare
time, run ID, or local paths;outcomeFingerprint only compares semantic adjudication and does not replace same-run evidence identity.
Managed execution
Unattended or multi-device tasks must first readManaged execution and device pool.
After submission, save both taskId and the first returned ownerToken; repeated submissions use the same
idempotencyKey + ownerToken, and cancellation is also only allowed by the original owner. A worker may only execute the exact serial and assignment
returned by the control plane, and may not choose devices on its own or rewrite the plan.
Task success is based on the terminal state of managed-report , a stable exit code, and per-shard evidence.
queued/running, a single shard passing, or the worker process exiting normally does not mean the matrix passed.
When a service restart or network interruption occurs, first recover the expired generation; late results from old assignments
must be rejected and cannot be manually written back.
On-device model
Before on-device decision-making, you must readOn-device Agent model deployment. The model package first
executes model-verify, then saves each typed receipt in the order install, benchmark, release-check, activate.
If signature, digest, compatibility, or release gate fails, stop; do not switch to an arbitrary key,
backend, or bypass the companion. The model done can still only end exploration; the final result only depends on the unified report formed by Result Judge
based on the checkpoint oracle, required cleanup, and evidence from this run.
Test cases and replay
Before creating or modifying a test case, read Test case authoring; when actions are involved, also read Action catalog. Basic closed loop:
scripts/solopi-ai --pretty doctor
scripts/solopi-ai --pretty apps
scripts/solopi-ai --pretty actions
scripts/solopi-ai --pretty cases
scripts/solopi-ai --pretty case-get --case "payment-smoke" --output cases/payment-smoke.json
scripts/solopi-ai --pretty case-validate --file cases/payment-smoke.json --output cases/payment-smoke.import.json
scripts/solopi-ai --pretty case-import --file cases/payment-smoke.import.json
scripts/solopi-ai --pretty run --case "payment-smoke" --run-timeout 600 --artifacts artifacts/payment-smoke
scripts/solopi-ai --pretty result --run-id '<run-id>'
- Only treat the terminal state
passed, at least one replay result, and exit code0as passing. run --no-waitexit code0only indicates that the request was accepted; continue querying with the savedrunId.run-repeatandrun-batchare orchestrations of multiple independent runs. Keep each sub-run'srunIdand result; if any sub-run fails, the aggregated result must not be used to conceal it.run、run-repeatandrun-batchcan use--target-packageto override the target for this run, and use--restart-appor--no-restart-appto override the restart policy for this run; overrides only apply to this run and are not written back to the test case or global settings. The target must be installed, have a Launcher, and must not be SoloPi itself.case-validate、case-importand allrun*commands apply the same safety policy to the entire test case: always reject historicalEXECUTE_SHELL, internalHANDLE_PERMISSION_ALERT、HIDE_INPUT_METHOD, and Provider upload URLs;CLEAR_DATA、KILL_PROCESS、JUMP_TO_PAGEmust explicitly use--confirm-high-risk. The first three items can only be viewed throughcase-step-list, and cannot be imported or replayed by the CLI.- Before replay, save the exact
caseIdandcaseFingerprintreturned by the device; the fingerprint covers the complete content actually loaded, decrypted, and inlined from the external step file, and the launch request must carry both and the newrequestId. The App only executes this immutable snapshot; if a test case with the same name is replaced, modified, or its step file is rewritten in place after precheck, it must fail, and same-name replays from other clients must not be claimed by this request. - Image comparison and in-test-case screen recording actions are only replayed when the required plugins have been installed via local files, restarted, and are in a loaded state; if missing, stop and report, and do not trigger remote downloads.
- Canceling a replay must use the one saved by the start command
runId:cancel --run-id '<run-id>'. When the currently active run does not match, stop; do not cancel another caller's task. - A multi-parameter test case is not
run-batch. First usecase-getto export the test case, then usecase-validate --running-params-file <文件>to write and validate theSEPARATEorUNIONparameter set, and finally usecase-import --replaceto update the exact test case; when clearing the configuration, use--clear-running-params。 case-deleteis an irreversible device change. First usecase-getto save the needed copy, and obtain the user's intent to delete the exact test case name.- By default
runwill set the replay auto-start configuration; when modification is not allowed, use--no-auto-start, and first confirm that the device has this configuration enabled.
Interactive recording
record-start is only responsible for creating a recording session on the exact app and entering a recordable state. Business touch, text input, page navigation, and the end timing are completed by the user on the phone; the CLI must not fake "manually recorded," nor automatically operate real accounts or payment pages without authorization.
- From
appsselect the exact package name, then runrecord-start, savesessionId。 - Only when
record-status --session-id <id>returns the device-declared active recording state may the user be prompted to begin manual operation. - After the user explicitly completes the operation, use the same
sessionIdto executerecord-stop。 - Only when the stop succeeds in a terminal state and returns a new test case identifier, run
cases/case-getto verify the recording result. - On timeout, interruption, or user abandonment, also query and stop the same session; do not stop recordings created by the manual interface or other agents.
History
Replay and performance history use replay-history-* and perf-history-*respectively. First use *-history-list --limit <1..500> to obtain the opaque id, then use the same id to query details or delete. Do not guess identifiers based on time, name, or list position. Replay details only provide bounded metadata, JSON content, and log previews; the current CLI cannot export the complete catalog of the App history page, and must not use run --artifacts to impersonate a complete history export.
replay-history-delete and perf-history-delete are irreversible changes. Before deletion, use the corresponding get to save the needed details, obtain the user's intent to delete the exact id , and rely on the exact deletion receipt.
Standalone screen recording
screen-record-start will create a standalone sessionId, but the user must confirm the Android MediaProjection system popup on the device. When screen-record-status returns pending-user-confirmation , explicitly prompt the user to confirm; do not click the popup, fake authorization, or report that it has started. Only entering recording indicates that real encoding has started.
When stopping, use the original sessionId. When local evidence is needed, use screen-record-stop --output <新路径>; the CLI is only allowed to pull a non-empty MP4 of the same session from the device-declared capturesRoot . When abandoning at the pending-user-confirmation or not-yet-encoded starting stage, stopping with the original ID will return cancelledBeforeStart=true, no MP4 is produced, and late permission or preparation callbacks will no longer start; the current protocol cannot safely close an already displayed system popup on behalf of the user.
After screen recording stops normally, the returned device-side outputPath can be handed to video-analysis-start --video-path, and the action's --action-offset-ms and --difference-thresholdrelative to the recording start must be explicitly provided. Only analyze SoloPi ScreenCaptures 's directly affiliated non-empty MP4; save requestId, wait completed then read visualResponseTimeMs. A missing plugin, invalid path, concurrency conflict, or failed are not valid elapsed times.
Camera code scanning
scan-start creates an independent sessionId and opens the camera page. Camera permission and framing actions must be completed by the user on the phone;pending-camera-permission indicates waiting for user authorization,scanning indicates the camera is ready but the user still needs to aim at the QR code or barcode. The start command only waits for the page to enter an observable state; subsequently use the original ID to execute scan-status。
Only completed contains content、format and codeType. The CLI scanning branch always returns contentExecuted=false: even if the content is HTTP, HTTPS, or solopi://, it is only returned as data, without opening a web page or executing a Scheme. When canceling, only the exact sessionIdreturned by the start may be used; the manual code scanning page and the CLI session are mutually exclusive, and cannot take over or close a camera page owned by another party. After a timeout or interruption, use the original ID to query and execute scan-cancel; camera permission must not be silently granted by the CLI.
Plugin management
plugin-list returns installed plugins and stable pluginId。plugin-install --file <本地.zip> only accepts local files explicitly provided by the user; the CLI automatically calculates the SHA-256, stages them on the device under a controlled random name, and cleans up the staged files on success, failure, and interruption paths. Newly installed Apps use the repository ABI compatibility manifest by default, and the user can clear or replace it in the App; the CLI does not actively trigger remote downloads, nor may it bypass local package hash verification.
Install or plugin-remove --id <pluginId> only counts as a completed change when completed_restart_required is reached, but the new state has not yet taken effect; the user must be explicitly told that SoloPi needs to be restarted. Plugins contain dynamic code; before executing a change, verify the file source, exact hash, target device, and scope of impact; do not report "restart required" as "loaded".
Performance and stress testing
Performance testing must read performance testing. Metrics vary by device; first run perf-list. When on-site observation is needed, use perf-display-start/status/stop, and the status returns the current valuesbound to the lease; when CSV is needed, use perf-start/status/stop. The two types of sessions share the performance service and cannot run concurrently, and both are cleaned up according to the exact sessionId ;stopped only means the session stopped or data saving completed, not that the target was met.
Startup time uses the Android Activity Manager measurement; first verify the exact package name from apps or user-provided information, then execute:
scripts/solopi-ai --pretty startup-time \
--target-package "com.example.pay" \
--mode cold \
--iterations 5 \
--interval 1
The command automatically resolves the Launcher Activity, strictly reads LaunchState、Activity、TotalTime、WaitTimeon each round, and reads the system's optional ThisTime. When a system such as Android 16 does not provide ThisTime , output null and unavailable statistics, and do not fabricate data. If a required field in any round is invalid, the entire command fails, and no summary is generated from partial rounds. This result is the startup time reported by Activity Manager; when the UI visual completion time is needed, use video-analysis-*after an independent screen recording, and the two measurements must not be mixed.
Stress testing likewise uses an independent sessionId. Select only the CPU or memory parameter boundaries exposed by the CLI; do not create load yourself through the Shell. Before executing stress, establish cleanup responsibility:
scripts/solopi-ai --pretty stress-start --cpu-count 1 --cpu-percent 50 --duration 60
scripts/solopi-ai --pretty stress-status --session-id '<session-id>'
scripts/solopi-ai --pretty stress-stop --session-id '<session-id>'
Regardless of whether the business replay passes, fails, times out, or is interrupted, stop the same stress session during the cleanup phase and confirm the final state. If stopping cannot be confirmed, explicitly report that the device may still be under stress, and do not start the next round of testing.
Success and evidence
Replay completion must simultaneously satisfy: the CLI exit code is 0, the status is passed、results non-empty; when requesting --artifacts , it must also be confirmed that result.json、screen.png、logcat.txt exists. On failure, retain and report exceptionMessage、exceptionStep and exceptionStepId。
Change commands such as configuration, import, deletion, video analysis, recording, code scanning, plugins, and stress must verify the returned requestId or sessionId; commands with sessions must verify the exact sessionId, and history and plugins must respectively verify the opaque id and the stable pluginId. Plugin final state completed_restart_required only proves that the change was persisted, not that the new code has been loaded. The "latest state" must not be passed off as evidence of the target request or target session.
Reference materials
- Capability matrix: Distinguish direct CLI, indirect via test cases, user interaction, and not yet safely automatable across ten capability domains.
- App feature coverage checklist: Map Manifest pages, 25 settings, test case actions, sessions, and security boundaries item by item.
- CLI reference: Commands, parameters, default values, side effects, and fixed procedures.
- Action catalog: 66 Android enumerations, 4 test case management actions, 7 control actions that cannot be replayed normally, 3 view-only actions, and 6 built-in dynamic Provider actions.
- Test case authoring: Real selectors, test case structure, dynamic actions, and the import closed loop.
- Performance testing: Performance collection, Android startup duration, video differential response duration, stress sessions, data, and automatic cleanup.
- Protocol: Query/change transport boundaries, state machine, identifier ownership, and exit codes.
- Fault handling: Device, permissions, recording, performance, stress, timeouts, and recovery.
- Managed execution and device pool: Device matrix, persistent queue, generation leases, CI/API, recovery, and evidence governance.
- On-device Agent model deployment: Runtime selection, signed packages, atomic installation/rollback, provider routing, benchmarks, and release gates.
Security constraints
- Operate only on devices, applications, test cases, and configurations that the user has explicitly included in scope; do not silently grant permissions, enable accessibility features, or modify device security settings.
- Do not provide or bypass to arbitrary Shell, arbitrary Scheme, or arbitrary HTTP; high-risk actions in existing test cases must also have their content and authorization verified first.
- Configuration only allows the keys and value types published by
config-list. Sensitive configuration, performance/screen recording upload addresses, remote plugin sources, and internal ADB addresses can only be handled in the App interface; unknown items and out-of-range values must be rejected. Before modifying the 17 ordinary writable items, save the old values, and if necessary restore them precisely viaconfig-set. - Only one owner is allowed for the same type of active session. Stop operations must carry the exact identifier returned at startup, and recording, performance, or stress sessions of unknown owners must not be cleaned up.
- Business failures and caller interruptions cannot skip cleanup. Stress loads must be stopped first; performance and screen recording must also have their final states confirmed.
- Plugins are dynamic code. Only install local packages explicitly specified by the user, verify the SHA-256 and exact
pluginId, and after installation or removal report the risk that a restart is required. - Do not fabricate node selectors. Base this on the actual output of
case-getorinspect, and preserve package name boundaries. - Test case imports, deletions, configuration changes, screenshots, logs, screen recordings, and performance files may all contain sensitive information; use new controlled paths, and do not automatically upload or send them externally.