From repeated clicks to reusable commands

Make browser work reusable

Turn a browser workflow into a site-specific CLI command you can run again, script, and inspect as JSON.

✓ Connecting to Chrome CDP...
✓ Analyzing page structure...
✓ LLM planning workflow...
✓ CLI commands generated to ~/.cliany-site/adapters/github.com/

{"ok": true, "data": {"results": [...]}}

Try it in three commands

Install, see the next safe step, then choose a maintained example before connecting an LLM.

01

Install

Get the CLI from PyPI.

pip install cliany-site
02

Check readiness

Read the human-friendly next step for your machine.

cliany-site doctor
03

Choose a maintained example

Browse public cases and their current validation paths before you configure Chrome/CDP or an LLM for your own workflow.

cliany-site cases

Follow the 10-minute guide →

Core Features

4 core capabilities + 12 extended capabilities

Start with the core four, then enable advanced capabilities on demand.

01 CORE

Zero-Intrusion Exploration

Injection-free AXTree exploration to quickly locate automatable paths.

02 CORE

LLM-Driven Code Generation

Turn page semantics directly into executable CLI commands.

03 CORE

Standard JSON Output

Unified {ok,data,error} output for easy automation integration.

04 CORE

Persistent Sessions

Reuse one login across commands to eliminate repetitive operations.

🩹

Smart Self-Healing

AXTree snapshot diffing, hot-patch selectors without re-exploring.

✂️

Smart DOM Pruning

4-layer AXTree pruning reduces LLM token usage by up to 50% for complex pages.

Lazy Adapter Registry

On-demand adapter loading accelerates CLI startup times significantly.

🔍

Diagnostic Mode

AI-powered root cause analysis for command execution failures.

📋

Metadata Schema v3

Enforces v3 metadata with `migrate` utility to auto-upgrade legacy adapters.

🔒

File Lock Protection

Concurrent-safe manifest and session writes via portalocker — no corruption under parallel processes.

🛡️

Tar Path Traversal Guard

Adapter import rejects archives with absolute paths, traversal segments, or symlink escapes.

🔄

Download Retry

Obscura binary downloads automatically retry on transient network failures with exponential back-off.

🗂️

Unified Error Codes

All error paths now carry machine-readable error codes and actionable fix hints in the JSON envelope.

Extended Capabilities (12)

Hide complexity by default, unlock it when needed.

  • Dynamic Adapter Loading
  • Chrome Auto-Management
  • Incremental Adapter Merge
  • Atomic Command System
  • Smart Recording Validation
  • TUI Management Interface
  • Headless & Remote Browser
  • YAML Workflow Orchestration
  • Data-Driven Batch Execution
  • Python SDK & HTTP API
  • Security Hardening
  • Adapter Marketplace

Real-World Use Cases

Explore once, own your CLI forever

🔥

GitHub as Your CLI

Tired of repetitive clicks on GitHub? Search repos and view READMEs directly from your terminal.

Browser → Search → Click repo → View README

5 steps · ~30s

Single command, structured JSON, pipe-friendly

1 command · Instant
✓ Adapter generated at ~/.cliany-site/adapters/github.com/
{"ok": true, "data": {"results": [...]}}
💡

Enterprise CRM: Login & Query

Stuck with a legacy CRM with no API? Generate a dedicated CLI for any web portal in minutes.

Login → CRM → Search → Details → Orders → Filter

5 steps · ~1m

Login once, then list-accounts --json

1 command · Instant
$ cliany-site login https://demo.suiteondemand.com/
✓ Session saved for demo.suiteondemand.com

$ cliany-site demo.suiteondemand.com list-accounts --limit 5 --json
{"ok": true, "data": {"accounts": [...], "count": 5}}
🚀

Team Toolbox

Stop wasting time on internal portal onboarding. Explore once, share adapters, and level up the whole team.

10+ docs + constant "where is this?" questions

Fragmented knowledge · High friction

Install shared adapters for instant access

Unified CLI · Zero learning curve
$ cliany-site issues.apache.org list-issues --project SPARK --limit 5 --json
{"ok": true, "data": {"issues": [...]}}

$ cliany-site cwiki.apache.org search-pages --space SPARK --query "release" --json
{"ok": true, "data": {"results": [...]}}

$ cliany-site builds.apache.org list-jobs --json
{"ok": true, "data": {"jobs": [...]}}

How It Works

Three steps from web pages to CLI commands

1

Explore

Specify a target URL and task description — the LLM automatically analyzes page structure and plans the action path.

cliany-site explore "https://github.com" "search repos"
2

Generate

Transform exploration results into Python/Click CLI tools, automatically saved to the local adapter directory.

~/.cliany-site/adapters/github.com/commands.py
3

Run

Replay workflows with generated CLI commands. Fuzzy matching ensures stable execution even after minor page changes.

cliany-site github.com search --query "browser-use" --json

CLI Reference

$ cliany-site doctor --json
{"ok": true, "data": {"cdp": true, "llm": true}}

$ cliany-site login "https://github.com" --json
✓ Waiting for browser login...
✓ Session saved to ~/.cliany-site/sessions/

$ cliany-site explore "https://github.com" "Search repos and view README" --json
✓ Exploration complete, adapter generated

$ cliany-site list --json
{"ok": true, "data": {"adapters": ["github.com"]}}

$ cliany-site github.com search --query "browser-use" --json
{"ok": true, "data": {"results": [...]}}
Generated list/search/read/extract commands, and any command with an extract action, default to expects_nonempty=true; empty, missing, or partial data fails. Declare expects_nonempty=false only when zero matches are valid; installed adapters are not silently rewritten.

10-Minute Success Path

Browse maintained cases before configuring an LLM for your own commands

Step 1: Install

# PyPI install (v0.12.0+)
pip install cliany-site

# Or install from source
git clone https://github.com/pearjelly/cliany.site.git
cd cliany-site
pip install -e .

Step 2: Check Readiness

# Human-readable first-run summary
cliany-site doctor

# Machine-readable automation output
cliany-site doctor --json

# Optional live LLM provider preflight before explore
cliany-site doctor --llm-live --json

Step 3: Run an Active Demo or Browse Cases

# If doctor --json reports ready_for_demo_adapters=true,
# run data.summary.demo_adapter_quickstart.recommended_commands in order
# (install only when absent, then verify --strict; run the read-only demo only after it succeeds)

# Otherwise browse public cases and their current validation paths
cliany-site cases

# Machine-readable catalog for scripts
cliany-site cases --json

Step 4: Generate Your Own

# Configure LLM only when you are ready to explore
# Retryable provider outages return E_LLM_UNAVAILABLE
export CLIANY_LLM_PROVIDER=anthropic
export CLIANY_ANTHROPIC_API_KEY="sk-ant-..."
cliany-site explore "https://github.com" "search repos" --json

After Your First Success

Ran a real public workflow? Propose it through the Real Demo Case Proposal path so it can become a validated case with an offline JSON example.

  • Use the Real Demo Case Proposal issue template for public, read-only workflows; generate candidate promotion issues with cliany-site cases --case-id pypi-project-search --issue-template, including Acceptance Criteria, Primary Runbook, Command SHA-256, Promotion Command Plan Summary, JSON promotion_command_plan_summary / issue_template_promotion_command_plan_summary, Promotion Command Plan command_sha256 lines, source / missing metadata, Doctor Preflight Evidence Fields, Doctor Preflight Evidence Template, JSON doctor_preflight_evidence_template, doctor_preflight_evidence_template_field_count, doctor_preflight_evidence_template_sha256, doctor_preflight_state_fields, and doctor_preflight_state_statuses. The state fields are preflight_state.status, preflight_state.ready_for_adapter_package, preflight_state.primary_reason, preflight_state.reason_codes, and preflight_state.next_action; statuses are limited to ready, blocked, and missing_fields.
  • Candidate cases should point to cases/manifest.json, cases/examples/, python scripts/validate_cases.py --strict, cliany-site cases --status candidate --promotion-plan with llm_live_preflight, llm_live_preflight_command_sha256, primary_issue_template_command, and issue_template_json_command, human cliany-site cases --status candidate output with preflight_required, preflight_blocker, and runbook_first, doctor JSON with summary.llm_live_preflight and CDP blocker evidence, base cliany-site cases --case-id <id> --evidence-bundle --json output plus cliany-site cases --case-id <id> --evidence-bundle --doctor-json /tmp/cliany-doctor-preflight.json --json with primary_next_task_runbook, primary_next_task_acceptance_criteria, promotion_command_plan_summary, promotion_command_plan[*].command_sha256, doctor_preflight_evidence_fields, doctor_preflight_evidence_values, doctor_preflight_evidence_ok, doctor_preflight_evidence_missing_count, doctor_preflight_evidence_null_count, doctor_preflight_evidence_null_fields, and doctor_preflight_state, and python scripts/plan_next_iteration.py --issues-dir /tmp/cliany-candidate-issues / issue-metadata.json with candidate_promotions[*].issue_template_command, candidate_promotions[*].issue_template_json_command, candidate_promotions[*].promotion_command_plan_summary, Primary Acceptance Criteria, case_promotion_evidence_primary_llm_live_preflight_required, case_promotion_evidence_primary_llm_live_preflight_command_sha256, case_promotion_evidence_primary_llm_live_preflight_blocker_comment, case_promotion_evidence_primary_doctor_preflight_blocker_comment, case_promotion_evidence_primary_doctor_preflight_evidence_template_sha256, case_promotion_doctor_preflight_evidence_template_sha256, doctor_preflight_evidence_fields, doctor_preflight_state_fields, doctor_preflight_state_statuses, required_labels, required_label_count, required_labels_sha256, and case_promotion_evidence_primary_runbook_steps / hash drift checks.
  • Queue-only automation can compare doctor evidence drift from promotion_plan.primary_doctor_preflight_evidence_template_sha256, promotion_plan.primary_llm_live_preflight_command_sha256, candidate primary_doctor_preflight_evidence_template_sha256, and task_queue[*].doctor_preflight_evidence_template_sha256 / task_queue[*].llm_live_preflight_command_sha256 without opening a full evidence bundle.
  • Validation-only automation can read promotion_evidence_summary.primary_next_task.doctor_preflight_evidence_template_sha256 plus doctor_preflight_state_fields / doctor_preflight_state_statuses from scripts/validate_cases.py --json, primary_doctor_preflight_evidence_template_sha256 from scripts/validate_cases.py --report, or promotion_evidence_primary_doctor_preflight_evidence_template_sha256 / promotion_evidence_primary_llm_live_preflight_command_sha256 from plain scripts/validate_cases.py --strict stdout. Evidence bundles also expose doctor_preflight_evidence_selectors, mapping semantic fields such as checks[llm_live].details.error_code to actual doctor JSON selectors such as data.checks[name="llm_live"].details.error_code.
  • Before advancing the PyPI candidate, use the Candidate Promotion Runbook in docs/candidate-promotion-runbook.md for cliany-site doctor --llm-live --require-capability generate_adapters --json, adapter package, metadata validation, and online smoke; keep the target package name pypi.org-<version>.cliany-adapter.tar.gz.
  • First-time contributors can start from docs/good-first-issues.md for offline, locally verifiable tasks.

Maintainer Loop

Current baseline: v0.16.316. Tag Release creates GitHub Releases from reviewed versioned notes, and strict readiness blocks missing, empty, mismatched, or generated compare-only notes before a tag is pushed. Master CI and tag Release Preflight now run node --check site/script.js before publication. Static adapter checks reject symbolic-link directories, core files, and manifest files before reading or importing them. Direct root CLI adapter commands also validate a present manifest's declared file hashes before importing commands.py; a mismatch returns E_VERIFY_STATIC/ manifest_error; this local boundary does not establish browser, LLM, or third-party workflow readiness. Root CLI dispatch now also runs the generated-module source-safety scan before import; banned patterns and non-UTF-8 modules return local E_VERIFY_STATIC/ security_issue and are not imported. Python and HTTP integrations can run the same static adapter gate with ClanySite.verify(domain), synchronous verify(domain), or GET /verify?domain=<domain> before browser work; this does not establish Chrome, LLM, or third-party workflow readiness. A discovered current-schema adapter that cannot register now returns structured E_VERIFY_STATIC details instead of an ambiguous unknown-command error; run cliany-site verify <domain> --strict --json before any browser or LLM work. Failed structured extraction reports can now identify the 1-based result rows with a blank field through data.quality.field_blank_rows, without changing successful responses or quality gates. Ordinary human doctor first asks for a live provider preflight before it offers explore; if that explicit preflight fails, it prints the strict retry command while default doctor still does not call a provider. For JSON automation, ready_for_explore and generate_adapters.local_ready remain local configuration only; local_blockers explains only local prerequisites. A provider failure can keep local_ready=true while overall ready=false and live_blockers=["llm_live"]; require ready_for_live_explore=true before a real explore and follow the strict next_step otherwise. Candidate promotion now runs an explicit live-LLM capability gate, so an unavailable provider stops automation with a nonzero result while retaining the doctor evidence needed to explain the blocker. Generated adapters still replay semantic dropdown selections and Enter-based submissions, and explore refuses to write a named data command until that command owns quality-checked extraction evidence. Explicit verification of an absent adapter now returns ADAPTER_NOT_FOUND instead of a successful empty result; strict verification also rejects a commands.py module that cannot load or does not export a click.Group named cli, before a doctor-guided read-only command can run. Extract actions without a usable selector now report E_PARSE_FAILED rather than pretending success. Generated adapter commands now preserve failed JSON envelopes and exit nonzero, while an explicitly declared expects_nonempty=false empty result remains successful. HTTP API writes now reject non-object JSON and invalid control types with 400, while missing adapters/commands and temporarily unavailable Chrome/LLM dependencies map to 404 and 503 without discarding the JSON envelope. HTTP API startup now documents the same root browser options that the CLI passes into its server: use --headless before serve to launch Chrome for the service, or --cdp-url before serve to connect an existing remote browser; GET /health confirms reachability and reports the installed package version. A marketplace dry run only preflights the package, so install before verifying a named domain. Candidate issue templates that receive doctor evidence now lead with the current execution gate, whether an adapter package is runnable, the blocker reason, and the required next action before any executable command. Candidate issue templates keep later task commands separate, so human and automated handoffs cannot present a candidate explore as ready before its gate passes. Public candidate issue bodies can be audited against the current template; missing, duplicate, and unexpected labeled issues must be resolved before an explicit rewrite can run. The human-readable audit line now includes an unexpected issue's actual title and URL, so maintainers can locate that blocker without parsing JSON. Use the 1-3 releases/day loop, weekly maintainer loop, release readiness next_actions, website alias inspect, and PyPI version-specific publication audit to turn the roadmap into small verified releases. Doctor selects a published no-login demo from the packaged active case catalog and exposes recommended_commands: it uses verify --strict, so a static failure returns nonzero and blocks a sequential read-only command; an occupied install target begins at that gate, never auto-overwrites, and is not presented as a healthy adapter. It does not present a candidate or third-party online success as verified fact. Use cliany-site market publish github.com --version 1.0.0 --json to create a verified market archive; its data.package_sha256 is the lowercase 64-character hexadecimal SHA-256 of the completed archive. Use that value with --sha256 <64-hex-sha256>, or run cliany-site market install <package> --dry-run --json for a local preflight.

  • Start from docs/weekly-maintainer-loop.md when choosing the next release slice.
  • Read next_actions, weekly_commit_cadence_ok, release_count_today, max_daily_releases, daily_release_limit_ok, daily_release_capacity_remaining, daily_release_cap_blocked, and daily_release_resume_date from python scripts/release_readiness.py --json or python scripts/check_release_cadence.py --json; only the cadence report emits daily_release_capacity_remaining; when the daily cap pauses a tag, release_readiness.py --json also exposes daily_release_resume_command and daily_release_resume_command_sha256. After release, confirm GitHub Release plus pypi_version, pypi_latest_version, and pypi_release_version with python scripts/check_release_publication.py --remote --distribution --json.

Experimental: Obscura Browser Provider

Obscura is a lightweight alternative to Chrome, currently in experimental status. Chrome remains the default provider.

  • Explore Not Supported: Obscura does not yet support AXTree exploration. Use it for executing existing adapters.
  • Platforms: darwin-arm64, darwin-x86_64, linux-x86_64, windows-x86_64
  • Lifecycle Commands: install / use / status / clean / rollback / upgrade / doctor

Help shape the next workflow

A target URL, expected result, and reproducible steps are the most useful feedback.