surfsky-cli 0.0.2__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 (38) hide show
  1. surfsky_cli-0.0.2/.github/workflows/ci.yml +37 -0
  2. surfsky_cli-0.0.2/.github/workflows/release.yml +25 -0
  3. surfsky_cli-0.0.2/.gitignore +8 -0
  4. surfsky_cli-0.0.2/LICENSE +21 -0
  5. surfsky_cli-0.0.2/PKG-INFO +156 -0
  6. surfsky_cli-0.0.2/README.md +128 -0
  7. surfsky_cli-0.0.2/pyproject.toml +69 -0
  8. surfsky_cli-0.0.2/src/surfsky_cli/__init__.py +3 -0
  9. surfsky_cli-0.0.2/src/surfsky_cli/__main__.py +3 -0
  10. surfsky_cli-0.0.2/src/surfsky_cli/commands/__init__.py +0 -0
  11. surfsky_cli-0.0.2/src/surfsky_cli/commands/account.py +340 -0
  12. surfsky_cli-0.0.2/src/surfsky_cli/commands/actions.py +662 -0
  13. surfsky_cli-0.0.2/src/surfsky_cli/commands/page.py +304 -0
  14. surfsky_cli-0.0.2/src/surfsky_cli/commands/scrape.py +217 -0
  15. surfsky_cli-0.0.2/src/surfsky_cli/commands/session.py +184 -0
  16. surfsky_cli-0.0.2/src/surfsky_cli/commands/status.py +102 -0
  17. surfsky_cli-0.0.2/src/surfsky_cli/config.py +115 -0
  18. surfsky_cli-0.0.2/src/surfsky_cli/html.py +41 -0
  19. surfsky_cli-0.0.2/src/surfsky_cli/main.py +191 -0
  20. surfsky_cli-0.0.2/src/surfsky_cli/out.py +343 -0
  21. surfsky_cli-0.0.2/src/surfsky_cli/session.py +298 -0
  22. surfsky_cli-0.0.2/src/surfsky_cli/skill.md +167 -0
  23. surfsky_cli-0.0.2/src/surfsky_cli/snapshot.py +154 -0
  24. surfsky_cli-0.0.2/tests/conftest.py +192 -0
  25. surfsky_cli-0.0.2/tests/test_account.py +128 -0
  26. surfsky_cli-0.0.2/tests/test_actions.py +237 -0
  27. surfsky_cli-0.0.2/tests/test_config.py +94 -0
  28. surfsky_cli-0.0.2/tests/test_html.py +34 -0
  29. surfsky_cli-0.0.2/tests/test_integration.py +118 -0
  30. surfsky_cli-0.0.2/tests/test_live.py +62 -0
  31. surfsky_cli-0.0.2/tests/test_main.py +10 -0
  32. surfsky_cli-0.0.2/tests/test_out.py +264 -0
  33. surfsky_cli-0.0.2/tests/test_page.py +152 -0
  34. surfsky_cli-0.0.2/tests/test_scrape.py +82 -0
  35. surfsky_cli-0.0.2/tests/test_session.py +293 -0
  36. surfsky_cli-0.0.2/tests/test_session_cmd.py +224 -0
  37. surfsky_cli-0.0.2/tests/test_snapshot.py +101 -0
  38. surfsky_cli-0.0.2/tests/test_status.py +81 -0
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ test:
17
+ runs-on: ${{ matrix.os }}
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ os: [ubuntu-latest]
22
+ python-version: ["3.12", "3.13", "3.14"]
23
+ include:
24
+ - os: macos-latest
25
+ python-version: "3.13"
26
+ - os: windows-latest
27
+ python-version: "3.13"
28
+ steps:
29
+ - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
30
+ - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ enable-cache: true
34
+ - run: uv sync --locked --all-groups
35
+ - run: uv run ruff check .
36
+ - run: uv run ty check
37
+ - run: uv run pytest -q
@@ -0,0 +1,25 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment: pypi
11
+ permissions:
12
+ id-token: write # PyPI trusted publishing
13
+ contents: read
14
+ steps:
15
+ - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
16
+ - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
17
+ with:
18
+ python-version: "3.12"
19
+ - run: test "v$(uv version --short)" = "$GITHUB_REF_NAME"
20
+ - run: uv sync --locked --all-groups
21
+ - run: uv run pytest -q
22
+ - run: uv build
23
+ - run: uv run --isolated --no-project --with dist/*.whl surfsky --version
24
+ - run: uv run --isolated --no-project --with dist/*.tar.gz surfsky --version
25
+ - run: uv publish
@@ -0,0 +1,8 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ dist/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Surfsky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.5
2
+ Name: surfsky-cli
3
+ Version: 0.0.2
4
+ Summary: The Surfsky antidetect cloud browser from the terminal, for people and AI agents.
5
+ Project-URL: Homepage, https://surfsky.io
6
+ Project-URL: Documentation, https://docs.surfsky.io
7
+ Project-URL: Repository, https://github.com/surfskyio/surfsky-cli
8
+ Project-URL: Issues, https://github.com/surfskyio/surfsky-cli/issues
9
+ Author: Surfsky SDK contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: agents,antidetect,automation,browser,cli,scraping,surfsky
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: anyio>=4.4
22
+ Requires-Dist: beautifulsoup4>=4.9
23
+ Requires-Dist: click>=8.2
24
+ Requires-Dist: markdownify>=1.1
25
+ Requires-Dist: pydantic>=2.8
26
+ Requires-Dist: surfsky<0.1,>=0.0.6
27
+ Description-Content-Type: text/markdown
28
+
29
+ # surfsky-cli
30
+
31
+ Command-line access to [Surfsky](https://surfsky.io)'s antidetect cloud browsers.
32
+ Scrape pages, control browser sessions, and save logins in profiles.
33
+
34
+ Requires Python 3.12+ on macOS, Windows, or Linux.
35
+
36
+ ## Install
37
+
38
+ ```sh
39
+ uv tool install surfsky-cli
40
+ ```
41
+
42
+ Or use `pipx install surfsky-cli` or `pip install surfsky-cli`.
43
+
44
+ ## Set up credentials
45
+
46
+ Copy your API token and base URL from the [dashboard](https://app.surfsky.io).
47
+
48
+ **Linux (bash)**
49
+
50
+ ```bash
51
+ export SURFSKY_API_TOKEN='your-token'
52
+ export SURFSKY_API_BASE_URL='your-base-url'
53
+ surfsky status
54
+ ```
55
+
56
+ **macOS (zsh)**
57
+
58
+ ```zsh
59
+ export SURFSKY_API_TOKEN='your-token'
60
+ export SURFSKY_API_BASE_URL='your-base-url'
61
+ surfsky status
62
+ ```
63
+
64
+ **Windows (PowerShell)**
65
+
66
+ ```powershell
67
+ $env:SURFSKY_API_TOKEN = 'your-token'
68
+ $env:SURFSKY_API_BASE_URL = 'your-base-url'
69
+ surfsky status
70
+ ```
71
+
72
+ `--api-token` and `--base-url` override the environment variables. The CLI does
73
+ not save credentials. Session records go in `~/.surfsky`; set `SURFSKY_HOME`
74
+ to use another directory.
75
+
76
+ ## Scrape a page
77
+
78
+ ```sh
79
+ surfsky scrape https://example.com # markdown
80
+ surfsky scrape https://example.com --only-main-content # omit navigation, footers, forms
81
+ surfsky scrape https://example.com -f markdown,links --json --pretty
82
+ surfsky scrape https://example.com -f screenshot -o shot.png
83
+ surfsky scrape https://example.com --country us --proxy premium --os mac
84
+ ```
85
+
86
+ Formats: `markdown` (default), `html` (cleaned), `raw_html` (unmodified),
87
+ `links`, and `screenshot`. One format returns content; multiple formats return
88
+ JSON. In text mode, `-f screenshot -o file.png` saves PNG bytes; screenshot
89
+ output is otherwise base64.
90
+
91
+ By default, `scrape` starts a browser and closes it when finished. Use `--keep`
92
+ to leave it running and return its ID, or `--profile <uuid>` to use a saved
93
+ profile. `--session <uuid>` (or `SURFSKY_SESSION`) reuses the active tab and
94
+ navigates it to the URL. Omit the URL to read the current page.
95
+
96
+ ## Automate a browser
97
+
98
+ ```sh
99
+ surfsky session start --proxy premium --proxy-type mobile --country us
100
+ # prints <uuid>; pass it as --session <uuid> or export SURFSKY_SESSION=<uuid> once
101
+ surfsky goto https://google.com --session <uuid>
102
+ surfsky type 'textarea[name=q]' surfsky --session <uuid>
103
+ surfsky press Enter -s --session <uuid>
104
+ surfsky get text --session <uuid>
105
+ surfsky screenshot -o results.png --session <uuid>
106
+ surfsky session stop --session <uuid>
107
+ ```
108
+
109
+ A unique prefix of the session ID is enough, and `--session` can go anywhere
110
+ on the line.
111
+
112
+ Proxy, location and fingerprint flags are the same as for `scrape`:
113
+ `--proxy premium|shared|<url>`, `--country`, `--region`, `--city`,
114
+ `--proxy-type mobile`, and `--os win|mac|android`. Look up codes with
115
+ `surfsky proxy countries`, `surfsky proxy regions us`, and
116
+ `surfsky proxy cities us texas`; `surfsky proxy quota` shows remaining traffic.
117
+
118
+ `-s` returns a snapshot with references such as `[@11] combobox "Search"`.
119
+ Use a reference from your own output as the target of `click`, `type`, or
120
+ `fill`, for example `surfsky click @11`. CSS selectors and `text=words` also
121
+ work. Take a new snapshot after navigation or a tab switch;
122
+ each snapshot replaces the saved references.
123
+
124
+ Sessions are billed per minute, including idle time, until stopped or closed
125
+ by the idle timeout. Set the timeout with
126
+ `surfsky session start --idle-timeout <seconds>`; see `--help` for the default.
127
+ `surfsky status` reports the selected session's idle time and checks its
128
+ connection, resetting the idle timer. `surfsky session devtools` prints live
129
+ view and DevTools URLs.
130
+
131
+ To reuse cookies across sessions:
132
+ `surfsky profile create acct --country us --os win`, then
133
+ `surfsky session start --profile <uuid>`.
134
+
135
+ ## Use with coding agents
136
+
137
+ Run `surfsky skill --install` to install a Claude Code skill at
138
+ `.claude/skills/surfsky/SKILL.md`. For other agents, `surfsky skill` prints the
139
+ same instructions. The skill records the CLI version and includes upgrade
140
+ instructions. After upgrading with `uv tool install surfsky-cli@latest`, run
141
+ `surfsky skill --install` again to update it.
142
+
143
+ - Use `--json` or `SURFSKY_JSON=1`. Success includes `ok: true`; errors include
144
+ `ok: false` and an `error` object with `code`, `message`, `hint`, and `retryable`.
145
+ JSON errors go to stdout; text errors go to stderr.
146
+ - `-o <file>` saves output; `--pretty` indents JSON. For `screenshot`, `-o`
147
+ saves the PNG and `--json` returns its path and size.
148
+ - Exit codes: 0 success, 1 error, 2 usage, 3 missing or expired session,
149
+ 4 authentication, 5 timeout, 6 not found or stale reference, 7 quota or plan limit.
150
+
151
+ ## Development
152
+
153
+ ```sh
154
+ uv sync --all-groups
155
+ uv run pytest -q
156
+ ```
@@ -0,0 +1,128 @@
1
+ # surfsky-cli
2
+
3
+ Command-line access to [Surfsky](https://surfsky.io)'s antidetect cloud browsers.
4
+ Scrape pages, control browser sessions, and save logins in profiles.
5
+
6
+ Requires Python 3.12+ on macOS, Windows, or Linux.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ uv tool install surfsky-cli
12
+ ```
13
+
14
+ Or use `pipx install surfsky-cli` or `pip install surfsky-cli`.
15
+
16
+ ## Set up credentials
17
+
18
+ Copy your API token and base URL from the [dashboard](https://app.surfsky.io).
19
+
20
+ **Linux (bash)**
21
+
22
+ ```bash
23
+ export SURFSKY_API_TOKEN='your-token'
24
+ export SURFSKY_API_BASE_URL='your-base-url'
25
+ surfsky status
26
+ ```
27
+
28
+ **macOS (zsh)**
29
+
30
+ ```zsh
31
+ export SURFSKY_API_TOKEN='your-token'
32
+ export SURFSKY_API_BASE_URL='your-base-url'
33
+ surfsky status
34
+ ```
35
+
36
+ **Windows (PowerShell)**
37
+
38
+ ```powershell
39
+ $env:SURFSKY_API_TOKEN = 'your-token'
40
+ $env:SURFSKY_API_BASE_URL = 'your-base-url'
41
+ surfsky status
42
+ ```
43
+
44
+ `--api-token` and `--base-url` override the environment variables. The CLI does
45
+ not save credentials. Session records go in `~/.surfsky`; set `SURFSKY_HOME`
46
+ to use another directory.
47
+
48
+ ## Scrape a page
49
+
50
+ ```sh
51
+ surfsky scrape https://example.com # markdown
52
+ surfsky scrape https://example.com --only-main-content # omit navigation, footers, forms
53
+ surfsky scrape https://example.com -f markdown,links --json --pretty
54
+ surfsky scrape https://example.com -f screenshot -o shot.png
55
+ surfsky scrape https://example.com --country us --proxy premium --os mac
56
+ ```
57
+
58
+ Formats: `markdown` (default), `html` (cleaned), `raw_html` (unmodified),
59
+ `links`, and `screenshot`. One format returns content; multiple formats return
60
+ JSON. In text mode, `-f screenshot -o file.png` saves PNG bytes; screenshot
61
+ output is otherwise base64.
62
+
63
+ By default, `scrape` starts a browser and closes it when finished. Use `--keep`
64
+ to leave it running and return its ID, or `--profile <uuid>` to use a saved
65
+ profile. `--session <uuid>` (or `SURFSKY_SESSION`) reuses the active tab and
66
+ navigates it to the URL. Omit the URL to read the current page.
67
+
68
+ ## Automate a browser
69
+
70
+ ```sh
71
+ surfsky session start --proxy premium --proxy-type mobile --country us
72
+ # prints <uuid>; pass it as --session <uuid> or export SURFSKY_SESSION=<uuid> once
73
+ surfsky goto https://google.com --session <uuid>
74
+ surfsky type 'textarea[name=q]' surfsky --session <uuid>
75
+ surfsky press Enter -s --session <uuid>
76
+ surfsky get text --session <uuid>
77
+ surfsky screenshot -o results.png --session <uuid>
78
+ surfsky session stop --session <uuid>
79
+ ```
80
+
81
+ A unique prefix of the session ID is enough, and `--session` can go anywhere
82
+ on the line.
83
+
84
+ Proxy, location and fingerprint flags are the same as for `scrape`:
85
+ `--proxy premium|shared|<url>`, `--country`, `--region`, `--city`,
86
+ `--proxy-type mobile`, and `--os win|mac|android`. Look up codes with
87
+ `surfsky proxy countries`, `surfsky proxy regions us`, and
88
+ `surfsky proxy cities us texas`; `surfsky proxy quota` shows remaining traffic.
89
+
90
+ `-s` returns a snapshot with references such as `[@11] combobox "Search"`.
91
+ Use a reference from your own output as the target of `click`, `type`, or
92
+ `fill`, for example `surfsky click @11`. CSS selectors and `text=words` also
93
+ work. Take a new snapshot after navigation or a tab switch;
94
+ each snapshot replaces the saved references.
95
+
96
+ Sessions are billed per minute, including idle time, until stopped or closed
97
+ by the idle timeout. Set the timeout with
98
+ `surfsky session start --idle-timeout <seconds>`; see `--help` for the default.
99
+ `surfsky status` reports the selected session's idle time and checks its
100
+ connection, resetting the idle timer. `surfsky session devtools` prints live
101
+ view and DevTools URLs.
102
+
103
+ To reuse cookies across sessions:
104
+ `surfsky profile create acct --country us --os win`, then
105
+ `surfsky session start --profile <uuid>`.
106
+
107
+ ## Use with coding agents
108
+
109
+ Run `surfsky skill --install` to install a Claude Code skill at
110
+ `.claude/skills/surfsky/SKILL.md`. For other agents, `surfsky skill` prints the
111
+ same instructions. The skill records the CLI version and includes upgrade
112
+ instructions. After upgrading with `uv tool install surfsky-cli@latest`, run
113
+ `surfsky skill --install` again to update it.
114
+
115
+ - Use `--json` or `SURFSKY_JSON=1`. Success includes `ok: true`; errors include
116
+ `ok: false` and an `error` object with `code`, `message`, `hint`, and `retryable`.
117
+ JSON errors go to stdout; text errors go to stderr.
118
+ - `-o <file>` saves output; `--pretty` indents JSON. For `screenshot`, `-o`
119
+ saves the PNG and `--json` returns its path and size.
120
+ - Exit codes: 0 success, 1 error, 2 usage, 3 missing or expired session,
121
+ 4 authentication, 5 timeout, 6 not found or stale reference, 7 quota or plan limit.
122
+
123
+ ## Development
124
+
125
+ ```sh
126
+ uv sync --all-groups
127
+ uv run pytest -q
128
+ ```
@@ -0,0 +1,69 @@
1
+ [project]
2
+ name = "surfsky-cli"
3
+ version = "0.0.2"
4
+ description = "The Surfsky antidetect cloud browser from the terminal, for people and AI agents."
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ keywords = ["surfsky", "cli", "browser", "automation", "scraping", "antidetect", "agents"]
9
+ authors = [{ name = "Surfsky SDK contributors" }]
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ "Environment :: Console",
13
+ "Intended Audience :: Developers",
14
+ "Programming Language :: Python :: 3 :: Only",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3.13",
17
+ "Programming Language :: Python :: 3.14",
18
+ ]
19
+ dependencies = [
20
+ "surfsky>=0.0.6,<0.1",
21
+ "click>=8.2",
22
+ "markdownify>=1.1",
23
+ "anyio>=4.4",
24
+ "pydantic>=2.8",
25
+ "beautifulsoup4>=4.9",
26
+ ]
27
+
28
+ [project.scripts]
29
+ surfsky = "surfsky_cli.main:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://surfsky.io"
33
+ Documentation = "https://docs.surfsky.io"
34
+ Repository = "https://github.com/surfskyio/surfsky-cli"
35
+ Issues = "https://github.com/surfskyio/surfsky-cli/issues"
36
+
37
+ [dependency-groups]
38
+ dev = ["pytest>=8.3", "ruff>=0.6", "ty>=0.0.56"]
39
+
40
+ [build-system]
41
+ requires = ["hatchling"]
42
+ build-backend = "hatchling.build"
43
+
44
+ [tool.hatch.build.targets.sdist]
45
+ only-include = ["src", "tests", "README.md", "LICENSE", "pyproject.toml", ".github"]
46
+
47
+ [tool.hatch.build.targets.wheel]
48
+ packages = ["src/surfsky_cli"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ target-version = "py312"
55
+ line-length = 90
56
+ src = ["src", "tests"]
57
+
58
+ [tool.ruff.lint]
59
+ select = ["E", "F", "I", "UP", "B", "SIM"]
60
+ ignore = ["E501"]
61
+
62
+ [tool.ruff.lint.per-file-ignores]
63
+ "**/__init__.py" = ["F401"]
64
+
65
+ [tool.ty.environment]
66
+ python-version = "3.12"
67
+
68
+ [tool.ty.src]
69
+ include = ["src"]
@@ -0,0 +1,3 @@
1
+ from importlib.metadata import version
2
+
3
+ __version__ = version("surfsky-cli")
@@ -0,0 +1,3 @@
1
+ from .main import main
2
+
3
+ main()
File without changes