ui-locator-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. ui_locator_cli-0.1.0/.env.example +30 -0
  2. ui_locator_cli-0.1.0/.github/workflows/publish.yml +138 -0
  3. ui_locator_cli-0.1.0/.gitignore +48 -0
  4. ui_locator_cli-0.1.0/.python-version +1 -0
  5. ui_locator_cli-0.1.0/LICENSE +17 -0
  6. ui_locator_cli-0.1.0/PKG-INFO +498 -0
  7. ui_locator_cli-0.1.0/README.md +450 -0
  8. ui_locator_cli-0.1.0/bench/__init__.py +1 -0
  9. ui_locator_cli-0.1.0/bench/benchmark.py +196 -0
  10. ui_locator_cli-0.1.0/bench/compare_models.py +192 -0
  11. ui_locator_cli-0.1.0/bench/fixtures/benchmark.json +72 -0
  12. ui_locator_cli-0.1.0/bench/fixtures/login.png +0 -0
  13. ui_locator_cli-0.1.0/bench/fixtures/model_matrix.json +37 -0
  14. ui_locator_cli-0.1.0/bench/fixtures/settings.png +0 -0
  15. ui_locator_cli-0.1.0/bench/fixtures/toolbar.png +0 -0
  16. ui_locator_cli-0.1.0/bench/make_fixtures.py +122 -0
  17. ui_locator_cli-0.1.0/bench/model_matrix.py +82 -0
  18. ui_locator_cli-0.1.0/bench/scoring.py +99 -0
  19. ui_locator_cli-0.1.0/examples/annotate_demo.py +63 -0
  20. ui_locator_cli-0.1.0/examples/demo.py +104 -0
  21. ui_locator_cli-0.1.0/examples/locate_button.py +63 -0
  22. ui_locator_cli-0.1.0/examples/serve_mlx.py +94 -0
  23. ui_locator_cli-0.1.0/pyproject.toml +147 -0
  24. ui_locator_cli-0.1.0/src/ui_locator/__init__.py +54 -0
  25. ui_locator_cli-0.1.0/src/ui_locator/__main__.py +6 -0
  26. ui_locator_cli-0.1.0/src/ui_locator/api.py +329 -0
  27. ui_locator_cli-0.1.0/src/ui_locator/cli.py +765 -0
  28. ui_locator_cli-0.1.0/src/ui_locator/config.py +125 -0
  29. ui_locator_cli-0.1.0/src/ui_locator/coords.py +333 -0
  30. ui_locator_cli-0.1.0/src/ui_locator/errors.py +29 -0
  31. ui_locator_cli-0.1.0/src/ui_locator/image.py +59 -0
  32. ui_locator_cli-0.1.0/src/ui_locator/mapstore.py +313 -0
  33. ui_locator_cli-0.1.0/src/ui_locator/project.py +379 -0
  34. ui_locator_cli-0.1.0/src/ui_locator/prompting.py +113 -0
  35. ui_locator_cli-0.1.0/src/ui_locator/providers/__init__.py +7 -0
  36. ui_locator_cli-0.1.0/src/ui_locator/providers/_mlx_utils.py +91 -0
  37. ui_locator_cli-0.1.0/src/ui_locator/providers/base.py +31 -0
  38. ui_locator_cli-0.1.0/src/ui_locator/providers/cloud_cua.py +225 -0
  39. ui_locator_cli-0.1.0/src/ui_locator/providers/mlx_qwen.py +96 -0
  40. ui_locator_cli-0.1.0/src/ui_locator/providers/mlx_uitars.py +91 -0
  41. ui_locator_cli-0.1.0/src/ui_locator/providers/omniparser.py +26 -0
  42. ui_locator_cli-0.1.0/src/ui_locator/providers/openai_compat.py +184 -0
  43. ui_locator_cli-0.1.0/src/ui_locator/skill/SKILL.md +148 -0
  44. ui_locator_cli-0.1.0/src/ui_locator/skillcmd.py +222 -0
  45. ui_locator_cli-0.1.0/src/ui_locator/types.py +128 -0
  46. ui_locator_cli-0.1.0/tests/conftest.py +133 -0
  47. ui_locator_cli-0.1.0/tests/test_api.py +97 -0
  48. ui_locator_cli-0.1.0/tests/test_bench_scoring.py +87 -0
  49. ui_locator_cli-0.1.0/tests/test_benchmark_models.py +101 -0
  50. ui_locator_cli-0.1.0/tests/test_cli.py +71 -0
  51. ui_locator_cli-0.1.0/tests/test_cli_config.py +129 -0
  52. ui_locator_cli-0.1.0/tests/test_cli_map.py +197 -0
  53. ui_locator_cli-0.1.0/tests/test_coords.py +174 -0
  54. ui_locator_cli-0.1.0/tests/test_integration.py +38 -0
  55. ui_locator_cli-0.1.0/tests/test_map_api.py +177 -0
  56. ui_locator_cli-0.1.0/tests/test_mapstore.py +224 -0
  57. ui_locator_cli-0.1.0/tests/test_project.py +281 -0
  58. ui_locator_cli-0.1.0/tests/test_prompting.py +46 -0
  59. ui_locator_cli-0.1.0/tests/test_provider_choice.py +89 -0
  60. ui_locator_cli-0.1.0/tests/test_skill.py +286 -0
  61. ui_locator_cli-0.1.0/ui-locator-qwen.sh +28 -0
@@ -0,0 +1,30 @@
1
+ # ui-locator secrets.
2
+ #
3
+ # Non-secret settings (provider, endpoint, model, prompt style) belong in
4
+ # .ui-locator/config.toml, where they can be committed and switched with
5
+ # `--use <profile>`. Run `ui-locator init` to create it, then keep only keys
6
+ # here (this file, or .ui-locator/.env, is gitignored by that template).
7
+ #
8
+ # Check what actually resolved with: ui-locator config show
9
+
10
+ UI_LOCATOR_OPENAI_API_KEY=<your-api-key>
11
+ # UI_LOCATOR_ANTHROPIC_API_KEY=<your-anthropic-api-key>
12
+
13
+ # Everything below can equally live in .ui-locator/config.toml; environment
14
+ # variables win over it, which makes them handy for one-off overrides.
15
+
16
+ # UI_LOCATOR_USE=qwen-cloud # pick a [models.<name>] profile
17
+ # UI_LOCATOR_PROVIDER=openai
18
+ # UI_LOCATOR_OPENAI_BASE_URL=https://api.fireworks.ai/inference/v1
19
+ # UI_LOCATOR_OPENAI_MODEL=accounts/fireworks/models/qwen3p7-plus
20
+ # UI_LOCATOR_OPENAI_PROMPT=qwen # required for Qwen: parses <box>, not <point>
21
+
22
+ # Element map
23
+ # UI_LOCATOR_MAP_DIR=/path/to/map # default: <project>/.ui-locator/map
24
+ # UI_LOCATOR_SESSION=run-42 # tag learned entries
25
+ # UI_LOCATOR_USE_MAP=false # ignore stored positions
26
+ # UI_LOCATOR_VERIFY=true # re-check a crop before trusting one
27
+
28
+ # Misc
29
+ # UI_LOCATOR_THINK=true
30
+ # UI_LOCATOR_MAX_TOKENS=512
@@ -0,0 +1,138 @@
1
+ name: publish
2
+
3
+ # Publishes to PyPI when a GitHub release is published, so the release notes
4
+ # and the uploaded version are always the same event. Can also be run by hand
5
+ # against TestPyPI to rehearse.
6
+ on:
7
+ release:
8
+ types: [published]
9
+ workflow_dispatch:
10
+ inputs:
11
+ target:
12
+ description: Index to upload to
13
+ type: choice
14
+ default: testpypi
15
+ options: [testpypi, pypi]
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ # uv.lock is not committed, so CI resolves dependencies fresh -- exactly how a
22
+ # user installing from PyPI does. Both ends of the supported range are tested
23
+ # because typer 0.27 stopped being click-based, which a single "latest" job
24
+ # caught only by accident.
25
+ test:
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ typer: ["typer", "typer==0.16.0"]
31
+ name: test (${{ matrix.typer }})
32
+ steps:
33
+ - uses: actions/checkout@v7
34
+
35
+ - name: Install uv
36
+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
37
+
38
+ - name: Install the project
39
+ run: |
40
+ uv sync --extra dev
41
+ uv pip install '${{ matrix.typer }}'
42
+
43
+ - name: Lint
44
+ run: uv run --no-sync ruff check src tests bench
45
+
46
+ - name: Type-check
47
+ run: uv run --no-sync mypy
48
+
49
+ - name: Test
50
+ run: uv run --no-sync pytest -q
51
+
52
+ build:
53
+ needs: test
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - uses: actions/checkout@v7
57
+
58
+ - name: Install uv
59
+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
60
+
61
+ - name: Install the project
62
+ run: uv sync --extra dev
63
+
64
+ # A tag that disagrees with pyproject.toml would publish a version nobody
65
+ # asked for, and PyPI never lets a version be reused.
66
+ - name: Check the tag matches the project version
67
+ if: github.event_name == 'release'
68
+ run: |
69
+ version=$(uv run python -c "import tomllib,pathlib;print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
70
+ tag="${GITHUB_REF_NAME#v}"
71
+ echo "pyproject: $version — tag: $tag"
72
+ if [ "$version" != "$tag" ]; then
73
+ echo "::error::tag '$GITHUB_REF_NAME' does not match version '$version' in pyproject.toml"
74
+ exit 1
75
+ fi
76
+
77
+ - name: Build sdist and wheel
78
+ run: uv build
79
+
80
+ # The skill is package data; if it ever falls out of the wheel,
81
+ # `ui-locator skill install` silently has nothing to install.
82
+ - name: Check the bundled skill is in the wheel
83
+ run: |
84
+ uv run python - <<'PY'
85
+ import glob, sys, zipfile
86
+ wheel = glob.glob("dist/*.whl")[0]
87
+ names = zipfile.ZipFile(wheel).namelist()
88
+ if "ui_locator/skill/SKILL.md" not in names:
89
+ sys.exit(f"SKILL.md missing from {wheel}")
90
+ print(f"ok: SKILL.md present in {wheel}")
91
+ PY
92
+
93
+ - uses: actions/upload-artifact@v7
94
+ with:
95
+ name: dist
96
+ path: dist/
97
+
98
+ publish:
99
+ needs: build
100
+ runs-on: ubuntu-latest
101
+ environment:
102
+ name: ${{ github.event_name == 'release' && 'pypi' || inputs.target }}
103
+ permissions:
104
+ id-token: write # PEP 740 attestations (and Trusted Publishing, see below)
105
+ env:
106
+ HAS_TEST_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN != '' }}
107
+ steps:
108
+ - uses: actions/download-artifact@v8
109
+ with:
110
+ name: dist
111
+ path: dist/
112
+
113
+ - name: Publish to TestPyPI
114
+ if: >-
115
+ github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
116
+ && env.HAS_TEST_TOKEN == 'true'
117
+ uses: pypa/gh-action-pypi-publish@release/v1
118
+ with:
119
+ repository-url: https://test.pypi.org/legacy/
120
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
121
+
122
+ - name: Note a skipped TestPyPI upload
123
+ if: >-
124
+ github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
125
+ && env.HAS_TEST_TOKEN != 'true'
126
+ run: |
127
+ echo "::notice::Built and round-tripped the artifacts; TestPyPI upload"\
128
+ " skipped because TEST_PYPI_API_TOKEN is not set."
129
+
130
+ - name: Publish to PyPI
131
+ if: github.event_name == 'release' || inputs.target == 'pypi'
132
+ uses: pypa/gh-action-pypi-publish@release/v1
133
+ with:
134
+ # Prefer Trusted Publishing: configure a publisher for this repo and
135
+ # workflow at https://pypi.org/manage/project/ui-locator-cli/settings/publishing/
136
+ # then delete the line below — GitHub mints a short-lived OIDC token
137
+ # per run and there is no long-lived secret to leak or rotate.
138
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,48 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ build/
8
+ dist/
9
+ .eggs/
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # uv
17
+ uv.lock
18
+
19
+ # Local secrets / environment
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+
24
+ # Local ui-locator project (config + element map) used while developing.
25
+ # In a real automation repo you *would* commit .ui-locator/config.toml and
26
+ # .ui-locator/map/ -- here it is just scratch, and .env holds a live API key.
27
+ .ui-locator/
28
+
29
+ # Annotated output of --annotate, and local working screenshots
30
+ *_test.png
31
+ /screen.png
32
+
33
+ # Tooling
34
+ .mypy_cache/
35
+ .ruff_cache/
36
+ .pytest_cache/
37
+ .coverage
38
+ htmlcov/
39
+
40
+ # Editor / OS
41
+ .DS_Store
42
+ .vscode/
43
+ .idea/
44
+
45
+ # Models / data (local caches)
46
+ weights/
47
+ *.pt
48
+ *.safetensors
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 ui-locator contributors
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.