assh-toolkit 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 (60) hide show
  1. assh_toolkit-0.1.0/.assh/README.md +9 -0
  2. assh_toolkit-0.1.0/.assh/scripts/README.md +3 -0
  3. assh_toolkit-0.1.0/.assh/templates/README.md +3 -0
  4. assh_toolkit-0.1.0/.gitattributes +2 -0
  5. assh_toolkit-0.1.0/.github/workflows/ci.yml +39 -0
  6. assh_toolkit-0.1.0/.github/workflows/docs.yml +60 -0
  7. assh_toolkit-0.1.0/.github/workflows/release.yml +65 -0
  8. assh_toolkit-0.1.0/.gitignore +23 -0
  9. assh_toolkit-0.1.0/AGENTS.md +88 -0
  10. assh_toolkit-0.1.0/PKG-INFO +125 -0
  11. assh_toolkit-0.1.0/README.md +111 -0
  12. assh_toolkit-0.1.0/docs/api-reference.mdx +172 -0
  13. assh_toolkit-0.1.0/docs/architecture.mdx +59 -0
  14. assh_toolkit-0.1.0/docs/contributing.mdx +41 -0
  15. assh_toolkit-0.1.0/docs/deployment.mdx +81 -0
  16. assh_toolkit-0.1.0/docs/docs.json +38 -0
  17. assh_toolkit-0.1.0/docs/examples.mdx +98 -0
  18. assh_toolkit-0.1.0/docs/getting-started.mdx +130 -0
  19. assh_toolkit-0.1.0/docs/index.mdx +59 -0
  20. assh_toolkit-0.1.0/docs/modules/cli.mdx +26 -0
  21. assh_toolkit-0.1.0/docs/modules/integrations.mdx +33 -0
  22. assh_toolkit-0.1.0/docs/modules/state.mdx +43 -0
  23. assh_toolkit-0.1.0/docs/modules/transport.mdx +42 -0
  24. assh_toolkit-0.1.0/docs/modules/worker.mdx +36 -0
  25. assh_toolkit-0.1.0/docs/testing.mdx +63 -0
  26. assh_toolkit-0.1.0/pyproject.toml +62 -0
  27. assh_toolkit-0.1.0/src/assh/__init__.py +5 -0
  28. assh_toolkit-0.1.0/src/assh/__main__.py +6 -0
  29. assh_toolkit-0.1.0/src/assh/cli.py +815 -0
  30. assh_toolkit-0.1.0/src/assh/constants.py +70 -0
  31. assh_toolkit-0.1.0/src/assh/integrations/__init__.py +1 -0
  32. assh_toolkit-0.1.0/src/assh/integrations/docker.py +25 -0
  33. assh_toolkit-0.1.0/src/assh/integrations/k8s.py +34 -0
  34. assh_toolkit-0.1.0/src/assh/models.py +167 -0
  35. assh_toolkit-0.1.0/src/assh/output.py +137 -0
  36. assh_toolkit-0.1.0/src/assh/paths.py +87 -0
  37. assh_toolkit-0.1.0/src/assh/remote_worker.py +283 -0
  38. assh_toolkit-0.1.0/src/assh/settings.py +53 -0
  39. assh_toolkit-0.1.0/src/assh/state.py +557 -0
  40. assh_toolkit-0.1.0/src/assh/transport.py +314 -0
  41. assh_toolkit-0.1.0/src/assh/worker_client.py +233 -0
  42. assh_toolkit-0.1.0/src/assh/workflows.py +190 -0
  43. assh_toolkit-0.1.0/tests/__init__.py +1 -0
  44. assh_toolkit-0.1.0/tests/conftest.py +74 -0
  45. assh_toolkit-0.1.0/tests/e2e/__init__.py +1 -0
  46. assh_toolkit-0.1.0/tests/e2e/test_vm_manual.py +181 -0
  47. assh_toolkit-0.1.0/tests/fixtures/scenarios/astra/bootstrap_remote.sh +26 -0
  48. assh_toolkit-0.1.0/tests/fixtures/scenarios/core/binary_payload.hex +1 -0
  49. assh_toolkit-0.1.0/tests/fixtures/scenarios/nexus/command_failure.sh +5 -0
  50. assh_toolkit-0.1.0/tests/fixtures/scenarios/nexus/command_success.sh +11 -0
  51. assh_toolkit-0.1.0/tests/fixtures/scenarios/nexus/metadata_wrapper.sh +20 -0
  52. assh_toolkit-0.1.0/tests/scenarios/__init__.py +1 -0
  53. assh_toolkit-0.1.0/tests/scenarios/conftest.py +202 -0
  54. assh_toolkit-0.1.0/tests/scenarios/helpers.py +126 -0
  55. assh_toolkit-0.1.0/tests/scenarios/models.py +79 -0
  56. assh_toolkit-0.1.0/tests/scenarios/test_astra_patterns.py +126 -0
  57. assh_toolkit-0.1.0/tests/scenarios/test_core_contracts.py +274 -0
  58. assh_toolkit-0.1.0/tests/scenarios/test_nexus_patterns.py +148 -0
  59. assh_toolkit-0.1.0/tests/test_cli.py +92 -0
  60. assh_toolkit-0.1.0/uv.lock +580 -0
@@ -0,0 +1,9 @@
1
+ # assh repo-local state
2
+
3
+ This directory is created and managed by `assh init`.
4
+
5
+ - `state.db` stores repo-local targets, env sets, k8s overrides, and task cache
6
+ - `config.toml` stores repo-local defaults
7
+ - `scripts/` contains tracked reusable repo workflows
8
+ - `templates/` contains tracked repo templates
9
+ - `logs/` and `sockets/` contain runtime artifacts and are ignored
@@ -0,0 +1,3 @@
1
+ # Repo workflow scripts
2
+
3
+ Put shared `.sh` or `.py` workflows here and run them with `assh script run <name>`.
@@ -0,0 +1,3 @@
1
+ # Repo templates
2
+
3
+ Put tracked reusable remote templates here for later script or bootstrap workflows.
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ checks:
12
+ name: Lint, Typecheck, Test, Build
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v5
17
+
18
+ - name: Setup Python
19
+ uses: actions/setup-python@v6
20
+ with:
21
+ python-version: "3.12"
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v6
25
+
26
+ - name: Sync dependencies
27
+ run: uv sync --group dev
28
+
29
+ - name: Ruff
30
+ run: uv run ruff check .
31
+
32
+ - name: Mypy
33
+ run: uv run mypy src
34
+
35
+ - name: Pytest
36
+ run: uv run pytest
37
+
38
+ - name: Build
39
+ run: uv build
@@ -0,0 +1,60 @@
1
+ name: Deploy Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - docs/**
8
+ - pyproject.toml
9
+ - .github/workflows/docs.yml
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+ pages: write
15
+ id-token: write
16
+
17
+ concurrency:
18
+ group: docs-pages
19
+ cancel-in-progress: true
20
+
21
+ env:
22
+ DOCS_SITE_URL: ${{ vars.DOCS_SITE_URL }}
23
+ DOCS_CUSTOM_DOMAIN: ${{ vars.DOCS_CUSTOM_DOMAIN }}
24
+
25
+ jobs:
26
+ build:
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v5
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v6
32
+ - name: Setup Python
33
+ run: uv python install 3.12
34
+ - name: Install Python dependencies
35
+ run: uv sync --group dev
36
+
37
+ - name: Build docs with Sparkify action
38
+ uses: SparkAIUR/sparkify@v1
39
+ with:
40
+ docs-dir: ./docs
41
+ out-dir: ./site
42
+ site: ${{ env.DOCS_SITE_URL }}
43
+ base: ""
44
+ strict: "true"
45
+ - name: Write CNAME
46
+ if: ${{ env.DOCS_CUSTOM_DOMAIN != '' }}
47
+ run: echo "${DOCS_CUSTOM_DOMAIN}" > site/CNAME
48
+ - uses: actions/upload-pages-artifact@v3
49
+ with:
50
+ path: site
51
+
52
+ deploy:
53
+ runs-on: ubuntu-latest
54
+ needs: build
55
+ environment:
56
+ name: github-pages
57
+ url: ${{ steps.deployment.outputs.page_url }}
58
+ steps:
59
+ - id: deployment
60
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,65 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ jobs:
10
+ verify:
11
+ name: Verify release candidate
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v5
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v6
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v6
26
+
27
+ - name: Sync dependencies
28
+ run: uv sync --group dev
29
+
30
+ - name: Ruff
31
+ run: uv run ruff check .
32
+
33
+ - name: Mypy
34
+ run: uv run mypy src
35
+
36
+ - name: Pytest
37
+ run: uv run pytest
38
+
39
+ pypi:
40
+ name: Build and Publish to PyPI
41
+ runs-on: ubuntu-latest
42
+ needs: verify
43
+ environment:
44
+ # Create this environment in the GitHub repository under Settings -> Environments
45
+ name: pypi
46
+ permissions:
47
+ id-token: write
48
+ contents: read
49
+ steps:
50
+ - name: Checkout
51
+ uses: actions/checkout@v5
52
+
53
+ - name: "Set up Python"
54
+ uses: actions/setup-python@v6
55
+ with:
56
+ python-version: "3.12"
57
+
58
+ - name: Install uv
59
+ uses: astral-sh/setup-uv@v6
60
+
61
+ - name: Build
62
+ run: uv build
63
+
64
+ - name: Publish
65
+ run: uv publish
@@ -0,0 +1,23 @@
1
+ /target
2
+ /artifacts
3
+ /dist-docs
4
+ /dist-docs-local
5
+ /.sparkify-docs
6
+ /tmp
7
+ /.venv
8
+ /.pytest_cache
9
+ /.ruff_cache
10
+ /.mypy_cache
11
+ **/__pycache__/
12
+ *.pyc
13
+ .DS_Store
14
+ .assh/*
15
+ !.assh/README.md
16
+ !.assh/scripts/
17
+ !.assh/scripts/**
18
+ !.assh/templates/
19
+ !.assh/templates/**
20
+ refs/docs/*
21
+ refs/tasks/*
22
+ refs/notes*
23
+ /.astro
@@ -0,0 +1,88 @@
1
+ # AGENTS
2
+
3
+ `assh` is an agentic SSH toolkit for stateful, token-efficient infrastructure workflows. This file is the tracked entrypoint for contributors and agentic tooling. If local internal docs exist under `refs/docs/`, start there for the detailed private source of truth; otherwise use this file and `docs/`.
4
+
5
+ <!-- assh:managed:start -->
6
+ ## assh Remote Execution Policy
7
+
8
+ Use `assh` instead of raw `ssh`, `scp`, `docker exec`, or `kubectl`
9
+ when you are operating on managed remote infrastructure for this repository.
10
+
11
+ - Run commands with `assh run "<command>" --target <alias>`
12
+ - Start long-running jobs with `assh task start "<command>" --target <alias>`
13
+ - Use `assh docker ...` and `assh k8s ...` helpers instead of composing
14
+ nested shell invocations manually
15
+ - Use `assh script run <name> --target <alias>` for tracked shared workflows
16
+ - Check `assh status` and `assh doctor` before inventing local state or
17
+ connection assumptions
18
+
19
+ Key rules:
20
+
21
+ - Prefer explicit `--target`, `--env-set`, `--namespace`, and `--context`
22
+ flags over hidden assumptions
23
+ - Do not invoke interactive full-screen commands such as `vim`, `nano`, `top`, or `less`
24
+ - `assh` tracks remote working directories and truncates oversized output automatically
25
+ - Default output is structured for non-TTY use and Rich-formatted for TTY use
26
+ <!-- assh:managed:end -->
27
+
28
+
29
+ ## Source map
30
+
31
+ - Public docs live in `docs/` and are written in Mintlify-compatible MDX.
32
+ - Private local docs live in `refs/docs/` and are gitignored by design.
33
+ - The internal scenario matrix lives in `refs/docs/SCENARIOS.md` when available locally.
34
+ - Runtime code lives under `src/assh/`.
35
+ - Tests live under `tests/`.
36
+ - Repo-local tracked workflow assets belong in `.assh/scripts/` and `.assh/templates/`.
37
+
38
+ ## Runtime architecture
39
+
40
+ - CLI orchestrator: `src/assh/cli.py`
41
+ - config resolver and settings loader: `src/assh/settings.py`
42
+ - state manager and SQLite layer: `src/assh/state.py`
43
+ - SSH transport worker: `src/assh/transport.py`
44
+ - output normalizer and serializers: `src/assh/output.py`
45
+ - repo/global workflow helpers: `src/assh/workflows.py`
46
+ - Docker and Kubernetes adapters: `src/assh/integrations/`
47
+ - remote worker payload: `src/assh/remote_worker.py`
48
+ - local worker client: `src/assh/worker_client.py`
49
+
50
+ ## Current command surface
51
+
52
+ - Top level: `init`, `doctor`, `status`, `version`, `run`, `chain`, `bg`, `push`, `fetch`, `logs`
53
+ - Target management: `target add`, `target remove`, `target list`, `target resolve`, `target import`
54
+ - Environment sets: `env set`, `env unset`, `env enable`, `env disable`, `env list`, `env show`
55
+ - Scripts: `script list`, `script validate`, `script run`
56
+ - Docker helpers: `docker ps`, `docker exec`, `docker logs`, `docker inspect`
57
+ - Kubernetes helpers: `k8s context set`, `k8s context clear`, `k8s context show`, `k8s get`, `k8s exec`, `k8s logs`
58
+ - Worker lifecycle: `worker deploy`, `worker health`, `worker upgrade`, `worker remove`
59
+ - Task lifecycle: `task start`, `task status`, `task logs`, `task kill`, `task list`
60
+
61
+ ## Contributing workflow
62
+
63
+ - Use `uv` for everything. `pyproject.toml` is the package and tooling source of truth.
64
+ - Install the dev environment with `uv sync --group dev`.
65
+ - Run the CLI with `uv run assh --help`.
66
+ - Run checks with `uv run pytest`, `uv run ruff check .`, and `uv run mypy src`.
67
+ - Run scenario coverage with `uv run pytest tests/scenarios`.
68
+ - Use `ASSH_E2E_ENABLE=1 uv run pytest -m e2e tests/e2e/test_vm_manual.py` only for intentional real-VM validation gates.
69
+ - Update `docs/*` when user-facing behavior changes.
70
+ - Update local `refs/docs/*` and `refs/docs/KB.md` when architecture, behavior, or operational knowledge changes.
71
+ - No Nexus- or Vela-derived scenario may execute `kubectl`.
72
+
73
+ ## Roadmap
74
+
75
+ - Sprint 0: source-of-truth docs, governance, and repo entrypoint
76
+ - Sprint 1: package skeleton, typed models, and settings
77
+ - Sprint 2: repo/global SQLite state, init flow, and legacy import
78
+ - Sprint 3: async SSH transport, output shaping, and batch execution
79
+ - Sprint 4: workflow scripts, Docker helpers, Kubernetes helpers, `doctor`, and `status`
80
+ - Sprint 5: remote worker deployment and task lifecycle
81
+ - Sprint 6: docs hardening, release validation, and MVP ship gate
82
+
83
+ ## Implementation status
84
+
85
+ - The initial package, CLI surface, state layer, output layer, transport, Docker/Kubernetes helpers, and remote worker client/payload are implemented.
86
+ - Public docs in `docs/` describe the current package surface.
87
+ - Internal private docs in `refs/docs/` are expected to carry deeper operational detail and ongoing knowledge capture.
88
+ - The scenario-driven validation suite now uses Astra and Nexus as executable SSH sources and Vela as modeled SSH edge-case input.
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: assh-toolkit
3
+ Version: 0.1.0
4
+ Summary: Agentic SSH toolkit for stateful, token-efficient infrastructure workflows.
5
+ Author: Codex
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: pydantic-settings<3.0.0,>=2.13.1
9
+ Requires-Dist: pydantic<3.0.0,>=2.12.5
10
+ Requires-Dist: pyyaml<7.0.0,>=6.0.3
11
+ Requires-Dist: rich<15.0.0,>=14.3.3
12
+ Requires-Dist: typer<0.25.0,>=0.24.1
13
+ Description-Content-Type: text/markdown
14
+
15
+ # assh
16
+
17
+ `assh` is an agentic SSH toolkit for stateful, token-efficient remote execution.
18
+
19
+ `assh` provides a typed Python package and CLI for:
20
+
21
+ - repo and global target resolution
22
+ - stateful remote execution with output shaping
23
+ - environment-set injection
24
+ - reusable workflow scripts
25
+ - Docker and Kubernetes helpers
26
+ - SSH-driven remote worker deployment and task lifecycle management
27
+
28
+ ## Status
29
+
30
+ `v0.1.0` is the first MVP release.
31
+
32
+ The current release includes:
33
+
34
+ - async-first SSH transport with persisted remote working directory state
35
+ - JSON, XML, and Rich output from a shared canonical result model
36
+ - repo-local and global SQLite-backed target and env-set state
37
+ - `push` and `fetch` helpers for remote file transfer
38
+ - deployable remote worker support for long-running task lifecycle control
39
+ - automated scenario coverage derived from Astra and Nexus workflows
40
+ - a guarded real-VM validation suite exercised against `root@192.237.244.107`
41
+
42
+ ## Install
43
+
44
+ ### Local development
45
+
46
+ ```bash
47
+ uv sync --group dev
48
+ uv run assh --help
49
+ ```
50
+
51
+ ### Install as a tool
52
+
53
+ ```bash
54
+ uv tool install --from . assh
55
+ ```
56
+
57
+ ## Quick start
58
+
59
+ ```bash
60
+ uv run assh init
61
+ uv run assh target add vm root@192.237.244.107
62
+ uv run assh run "uname -a && whoami && pwd" --target vm
63
+ ```
64
+
65
+ Persist a remote workspace across commands:
66
+
67
+ ```bash
68
+ uv run assh chain \
69
+ --target vm \
70
+ --step "mkdir -p /tmp/assh-demo" \
71
+ --step "cd /tmp/assh-demo" \
72
+ --step "printf 'hello from assh\n' > note.txt"
73
+
74
+ uv run assh run "pwd && cat note.txt" --target vm
75
+ ```
76
+
77
+ Use env sets with automatic redaction:
78
+
79
+ ```bash
80
+ uv run assh env set deploy APP_ENV production
81
+ uv run assh env set deploy API_TOKEN super-secret-token
82
+ uv run assh env enable deploy
83
+ uv run assh run "printf 'APP_ENV=%s\nTOKEN=%s\n' \"\$APP_ENV\" \"\$API_TOKEN\"" --target vm
84
+ ```
85
+
86
+ Use the remote worker for long-running tasks:
87
+
88
+ ```bash
89
+ uv run assh worker deploy --target vm
90
+ uv run assh task start "printf 'start\n'; sleep 10; printf 'done\n'" --target vm
91
+ uv run assh task list --target vm
92
+ uv run assh task logs <task-id> --target vm
93
+ ```
94
+
95
+ ## Validation
96
+
97
+ Core local checks:
98
+
99
+ ```bash
100
+ uv run ruff check .
101
+ uv run mypy src
102
+ uv run pytest
103
+ uv build
104
+ ```
105
+
106
+ Guarded real-VM validation:
107
+
108
+ ```bash
109
+ ASSH_E2E_ENABLE=1 \
110
+ ASSH_E2E_TARGET=root@192.237.244.107 \
111
+ ASSH_E2E_WORKDIR=/tmp/assh-scenarios \
112
+ ASSH_E2E_STRICT_HOSTKEY=accept-new \
113
+ uv run pytest -m e2e tests/e2e/test_vm_manual.py -vv
114
+ ```
115
+
116
+ ## Documentation
117
+
118
+ - [AGENTS.md](AGENTS.md) is the tracked repo entrypoint.
119
+ - [docs/](docs/) contains the public Mintlify docs.
120
+ - [docs/examples.mdx](docs/examples.mdx) contains copy-paste usage examples.
121
+
122
+ ## Release workflow
123
+
124
+ - `.github/workflows/ci.yml` runs lint, typecheck, tests, and package builds on pushes and pull requests.
125
+ - `.github/workflows/release.yml` verifies the tagged revision before publishing to PyPI.
@@ -0,0 +1,111 @@
1
+ # assh
2
+
3
+ `assh` is an agentic SSH toolkit for stateful, token-efficient remote execution.
4
+
5
+ `assh` provides a typed Python package and CLI for:
6
+
7
+ - repo and global target resolution
8
+ - stateful remote execution with output shaping
9
+ - environment-set injection
10
+ - reusable workflow scripts
11
+ - Docker and Kubernetes helpers
12
+ - SSH-driven remote worker deployment and task lifecycle management
13
+
14
+ ## Status
15
+
16
+ `v0.1.0` is the first MVP release.
17
+
18
+ The current release includes:
19
+
20
+ - async-first SSH transport with persisted remote working directory state
21
+ - JSON, XML, and Rich output from a shared canonical result model
22
+ - repo-local and global SQLite-backed target and env-set state
23
+ - `push` and `fetch` helpers for remote file transfer
24
+ - deployable remote worker support for long-running task lifecycle control
25
+ - automated scenario coverage derived from Astra and Nexus workflows
26
+ - a guarded real-VM validation suite exercised against `root@192.237.244.107`
27
+
28
+ ## Install
29
+
30
+ ### Local development
31
+
32
+ ```bash
33
+ uv sync --group dev
34
+ uv run assh --help
35
+ ```
36
+
37
+ ### Install as a tool
38
+
39
+ ```bash
40
+ uv tool install --from . assh
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ uv run assh init
47
+ uv run assh target add vm root@192.237.244.107
48
+ uv run assh run "uname -a && whoami && pwd" --target vm
49
+ ```
50
+
51
+ Persist a remote workspace across commands:
52
+
53
+ ```bash
54
+ uv run assh chain \
55
+ --target vm \
56
+ --step "mkdir -p /tmp/assh-demo" \
57
+ --step "cd /tmp/assh-demo" \
58
+ --step "printf 'hello from assh\n' > note.txt"
59
+
60
+ uv run assh run "pwd && cat note.txt" --target vm
61
+ ```
62
+
63
+ Use env sets with automatic redaction:
64
+
65
+ ```bash
66
+ uv run assh env set deploy APP_ENV production
67
+ uv run assh env set deploy API_TOKEN super-secret-token
68
+ uv run assh env enable deploy
69
+ uv run assh run "printf 'APP_ENV=%s\nTOKEN=%s\n' \"\$APP_ENV\" \"\$API_TOKEN\"" --target vm
70
+ ```
71
+
72
+ Use the remote worker for long-running tasks:
73
+
74
+ ```bash
75
+ uv run assh worker deploy --target vm
76
+ uv run assh task start "printf 'start\n'; sleep 10; printf 'done\n'" --target vm
77
+ uv run assh task list --target vm
78
+ uv run assh task logs <task-id> --target vm
79
+ ```
80
+
81
+ ## Validation
82
+
83
+ Core local checks:
84
+
85
+ ```bash
86
+ uv run ruff check .
87
+ uv run mypy src
88
+ uv run pytest
89
+ uv build
90
+ ```
91
+
92
+ Guarded real-VM validation:
93
+
94
+ ```bash
95
+ ASSH_E2E_ENABLE=1 \
96
+ ASSH_E2E_TARGET=root@192.237.244.107 \
97
+ ASSH_E2E_WORKDIR=/tmp/assh-scenarios \
98
+ ASSH_E2E_STRICT_HOSTKEY=accept-new \
99
+ uv run pytest -m e2e tests/e2e/test_vm_manual.py -vv
100
+ ```
101
+
102
+ ## Documentation
103
+
104
+ - [AGENTS.md](AGENTS.md) is the tracked repo entrypoint.
105
+ - [docs/](docs/) contains the public Mintlify docs.
106
+ - [docs/examples.mdx](docs/examples.mdx) contains copy-paste usage examples.
107
+
108
+ ## Release workflow
109
+
110
+ - `.github/workflows/ci.yml` runs lint, typecheck, tests, and package builds on pushes and pull requests.
111
+ - `.github/workflows/release.yml` verifies the tagged revision before publishing to PyPI.