shellflow 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 (36) hide show
  1. shellflow-0.1.0/.github/workflows/ci.yml +70 -0
  2. shellflow-0.1.0/.github/workflows/release.yml +73 -0
  3. shellflow-0.1.0/.gitignore +43 -0
  4. shellflow-0.1.0/.python-version +1 -0
  5. shellflow-0.1.0/.rumdl.toml +24 -0
  6. shellflow-0.1.0/AGENTS.md +67 -0
  7. shellflow-0.1.0/CHANGELOG.md +11 -0
  8. shellflow-0.1.0/CLAUDE.md +1 -0
  9. shellflow-0.1.0/Justfile +90 -0
  10. shellflow-0.1.0/PKG-INFO +253 -0
  11. shellflow-0.1.0/README.md +231 -0
  12. shellflow-0.1.0/assets/shellflow-run.png +0 -0
  13. shellflow-0.1.0/behave_runner.py +50 -0
  14. shellflow-0.1.0/cliff.toml +78 -0
  15. shellflow-0.1.0/context7.json +4 -0
  16. shellflow-0.1.0/features/__init__.py +1 -0
  17. shellflow-0.1.0/features/environment.py +73 -0
  18. shellflow-0.1.0/features/parser.feature +25 -0
  19. shellflow-0.1.0/features/runner.feature +57 -0
  20. shellflow-0.1.0/features/steps/__init__.py +1 -0
  21. shellflow-0.1.0/features/steps/shellflow_steps.py +237 -0
  22. shellflow-0.1.0/playbooks/hello.sh +8 -0
  23. shellflow-0.1.0/pyproject.toml +72 -0
  24. shellflow-0.1.0/ruff.toml +110 -0
  25. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/REFINEMENT_SUMMARY.md +165 -0
  26. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/design.md +1011 -0
  27. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/features/config.feature +115 -0
  28. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/features/parser.feature +131 -0
  29. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/features/runner.feature +119 -0
  30. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/features/steps/shellflow_steps.py +463 -0
  31. shellflow-0.1.0/specs/2026-03-13-01-shellflow-runner/tasks.md +146 -0
  32. shellflow-0.1.0/src/shellflow.py +802 -0
  33. shellflow-0.1.0/tests/__init__.py +1 -0
  34. shellflow-0.1.0/tests/fixtures/local_only.sh +6 -0
  35. shellflow-0.1.0/tests/test_shellflow.py +1356 -0
  36. shellflow-0.1.0/uv.lock +623 -0
@@ -0,0 +1,70 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version:
16
+ - "3.12"
17
+ - "3.13"
18
+
19
+ steps:
20
+ - name: Checkout repository
21
+ uses: actions/checkout@v5
22
+
23
+ - name: Set up uv
24
+ uses: astral-sh/setup-uv@v7
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ enable-cache: true
28
+ cache-dependency-glob: |
29
+ pyproject.toml
30
+ uv.lock
31
+
32
+ - name: Install dependencies
33
+ run: uv sync --all-groups
34
+
35
+ - name: Run tests
36
+ run: uv run pytest -q
37
+
38
+ - name: Run BDD scenarios
39
+ run: uv run behave features
40
+
41
+ quality:
42
+ runs-on: ubuntu-latest
43
+
44
+ steps:
45
+ - name: Checkout repository
46
+ uses: actions/checkout@v5
47
+
48
+ - name: Set up uv
49
+ uses: astral-sh/setup-uv@v7
50
+ with:
51
+ python-version: "3.12"
52
+ enable-cache: true
53
+ cache-dependency-glob: |
54
+ pyproject.toml
55
+ uv.lock
56
+
57
+ - name: Install dependencies
58
+ run: uv sync --all-groups
59
+
60
+ - name: Run formatting check
61
+ run: uv run ruff format --check .
62
+
63
+ - name: Run lint
64
+ run: uv run ruff check .
65
+
66
+ - name: Run type check
67
+ run: uv run ty check src tests
68
+
69
+ - name: Build distributions
70
+ run: uv build
@@ -0,0 +1,73 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Setup uv
21
+ uses: astral-sh/setup-uv@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Get version from tag
26
+ id: tag_version
27
+ run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
28
+
29
+ - name: Check pyproject.toml version
30
+ run: |
31
+ FILE_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
32
+
33
+ echo "pyproject.toml version: $FILE_VERSION"
34
+ echo "Tag version: ${{ env.VERSION }}"
35
+
36
+ if [ "$FILE_VERSION" != "${{ env.VERSION }}" ]; then
37
+ echo "Error: pyproject.toml version ($FILE_VERSION) does not match tag version (${{ env.VERSION }})"
38
+ exit 1
39
+ fi
40
+
41
+ - name: Generate Changelog
42
+ uses: orhun/git-cliff-action@v4
43
+ id: git-cliff
44
+ with:
45
+ config: cliff.toml
46
+ args: --verbose --latest --strip header
47
+ env:
48
+ OUTPUT: CHANGELOG.md
49
+
50
+ - name: Create GitHub Release
51
+ uses: softprops/action-gh-release@v2
52
+ with:
53
+ body: ${{ steps.git-cliff.outputs.content }}
54
+ prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
55
+
56
+ - name: Install dependencies
57
+ run: uv sync --all-groups
58
+
59
+ - name: Run release verification
60
+ run: |
61
+ uv run ruff format --check .
62
+ uv run ruff check .
63
+ uv run ty check src tests
64
+ uv run pytest -q
65
+ uv run behave features
66
+
67
+ - name: Build Package
68
+ run: uv build
69
+
70
+ - name: Publish to PyPI
71
+ env:
72
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
73
+ run: uv publish
@@ -0,0 +1,43 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ *.egg
11
+
12
+ # Virtual environment
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Testing / coverage
18
+ .pytest_cache/
19
+ .coverage
20
+ htmlcov/
21
+ .tox/
22
+ .nox/
23
+
24
+ # Ruff
25
+ .ruff_cache/
26
+
27
+ # ty
28
+ .ty/
29
+
30
+ # IDE
31
+ .idea/
32
+ .vscode/
33
+ *.swp
34
+ *.swo
35
+
36
+ # OS
37
+ .DS_Store
38
+ Thumbs.db
39
+
40
+ # Environment variables
41
+ .env
42
+ .env.local
43
+ .rumdl_cache/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,24 @@
1
+ # rumdl configuration file
2
+
3
+ # Global configuration options
4
+ [global]
5
+ # List of rules to disable (uncomment and modify as needed)
6
+ disable = ["MD013", "MD033", "MD041", "MD036"]
7
+
8
+ # List of file/directory patterns to exclude from linting
9
+ exclude = [
10
+ # Common directories to exclude
11
+ ".git",
12
+ ".github",
13
+ "node_modules",
14
+ "vendor",
15
+ "dist",
16
+ "build",
17
+ ".venv",
18
+ "venv",
19
+ "__pycache__",
20
+ "*.egg-info",
21
+
22
+ # Specific files or patterns
23
+ "CHANGELOG.md",
24
+ ]
@@ -0,0 +1,67 @@
1
+ # Shellflow Agent Instructions
2
+
3
+ ## Project Overview
4
+
5
+ Shellflow is a minimal shell script orchestrator with SSH support. It allows users to write shell scripts that execute across local and remote environments using simple comment markers.
6
+
7
+ ## Project Structure
8
+
9
+ ```text
10
+ shellflow/
11
+ ├── src/shellflow.py # Main module with all functionality
12
+ ├── tests/ # Unit tests (pytest)
13
+ ├── features/ # BDD acceptance tests (behave)
14
+ │ ├── parser.feature
15
+ │ ├── runner.feature
16
+ │ ├── steps/shellflow_steps.py
17
+ │ └── environment.py
18
+ ├── behave_runner.py # Wrapper for running behave
19
+ ├── pyproject.toml # Project configuration
20
+ ├── README.md # Documentation
21
+ └── AGENTS.md # This file
22
+ ```
23
+
24
+ ## Core Concepts
25
+
26
+ ### Script Block Markers
27
+
28
+ - `# @LOCAL` - Start a local execution block
29
+ - `# @REMOTE <host>` - Start a remote execution block
30
+
31
+ ### Key Modules
32
+
33
+ - `Block` - Represents an execution block (local or remote)
34
+ - `ExecutionContext` - Passes state between block executions
35
+ - `ExecutionResult` - Result of executing a single block
36
+ - `RunResult` - Result of running a complete script
37
+ - `SSHConfig` - SSH configuration for remote hosts
38
+
39
+ ### CLI Commands
40
+
41
+ ```bash
42
+ shellflow run <script> # Run a shellflow script
43
+ shellflow run <script> -v # Run with verbose output
44
+ shellflow --version # Show version
45
+ ```
46
+
47
+ ## Development Commands
48
+
49
+ ```bash
50
+ just format # Format code with ruff
51
+ just lint # Lint with ruff
52
+ just test # Run pytest
53
+ just bdd # Run behave BDD tests
54
+ just test-all # Run format, lint, test, and bdd
55
+ just typecheck # Type check with ty
56
+ ```
57
+
58
+ ## Testing
59
+
60
+ - Unit tests: `pytest` under `tests/`
61
+ - BDD tests: `behave` under `features/`
62
+ - Run all: `just test-all`
63
+
64
+ ## Dependencies
65
+
66
+ - Runtime: `paramiko>=3.0.0`
67
+ - Dev: `pytest`, `behave`, `ruff`, `ty`, `hypothesis`
@@ -0,0 +1,11 @@
1
+ ## [0.1.0] - 2026-03-15
2
+
3
+ ### Features
4
+
5
+ - Add public key to context7.json
6
+
7
+ ### Miscellaneous Tasks
8
+
9
+ - Update release workflow to improve version check and changelog generation
10
+
11
+ <!-- generated by git-cliff -->
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -0,0 +1,90 @@
1
+ # Default recipe to display help
2
+ default:
3
+ @just --list
4
+
5
+ # Sync all dependencies
6
+ sync:
7
+ uv sync --all-groups
8
+
9
+ # Format all code
10
+ format:
11
+ rumdl fmt .
12
+ uv run ruff format .
13
+ uv run ruff check --fix .
14
+
15
+ # Auto-fix linting issues
16
+ fix:
17
+ rumdl check --fix .
18
+ uv run ruff check --fix .
19
+
20
+ # Run all lints
21
+ lint:
22
+ typos
23
+ rumdl check .
24
+ uv run ruff check .
25
+ uv run ruff format --check .
26
+ uv run ty check src tests
27
+
28
+ # Run tests
29
+ test:
30
+ uv run pytest
31
+
32
+ # Run BDD scenarios
33
+ bdd:
34
+ uv run behave
35
+
36
+ # Run both TDD and BDD suites
37
+ test-all:
38
+ uv run pytest
39
+ uv run behave
40
+
41
+ # Run tests with coverage
42
+ test-coverage:
43
+ uv run pytest --cov=uv_app --cov-report=term-missing --cov-report=html
44
+
45
+ # Run benchmarks
46
+ bench:
47
+ uv run pytest -m benchmark --benchmark-only
48
+
49
+ # Build the package
50
+ build:
51
+ uv build
52
+
53
+ # Publish the package to PyPI
54
+ publish:
55
+ uv build
56
+ uv publish
57
+
58
+ # Type check with ty
59
+ typecheck:
60
+ uv run ty check src tests
61
+
62
+ # Check for Chinese characters
63
+ check-cn:
64
+ rg --line-number --column "\p{Han}"
65
+
66
+ # Full CI check
67
+ ci: lint test-all build
68
+
69
+ # ============================================================
70
+ # Maintenance & Tools
71
+ # ============================================================
72
+
73
+ # Clean build artifacts
74
+ clean:
75
+ rm -rf dist/ .pytest_cache/ .ruff_cache/ htmlcov/ .coverage
76
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
77
+ find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
78
+
79
+ # Install all required development tools
80
+ setup:
81
+ uv sync --all-groups
82
+ cargo install typos-cli
83
+
84
+ # Lock dependencies
85
+ lock:
86
+ uv lock
87
+
88
+ # Update all dependencies
89
+ update:
90
+ uv lock --upgrade
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: shellflow
3
+ Version: 0.1.0
4
+ Summary: A minimal shell script orchestrator with SSH support
5
+ Project-URL: Homepage, https://github.com/longcipher/shellflow
6
+ Project-URL: Repository, https://github.com/longcipher/shellflow
7
+ Project-URL: Issues, https://github.com/longcipher/shellflow/issues
8
+ Author: Bob Liu
9
+ License-Expression: Apache-2.0
10
+ Keywords: automation,orchestration,shell,ssh
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: System :: Systems Administration
19
+ Requires-Python: >=3.12
20
+ Requires-Dist: paramiko>=3.0.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # ShellFlow
24
+
25
+ [![DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/longcipher/shellflow)
26
+ [![Context7](https://img.shields.io/badge/Website-context7.com-blue)](https://context7.com/longcipher/shellflow)
27
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
28
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
29
+ [![PyPI](https://img.shields.io/pypi/v/shellflow.svg)](https://pypi.org/project/shellflow/)
30
+
31
+ ![shellflow](https://socialify.git.ci/longcipher/shellflow/image?font=Source+Code+Pro&language=1&name=1&owner=1&pattern=Circuit+Board&theme=Auto)
32
+
33
+ ShellFlow is a minimal shell script orchestrator for mixed local and remote execution. You write one shell script, mark execution boundaries with comments, and ShellFlow runs each block in order while resolving remote targets from your SSH configuration.
34
+
35
+ ![shellflow-run](assets/shellflow-run.png)
36
+
37
+ ## What It Does
38
+
39
+ - Split a shell script into `@LOCAL` and `@REMOTE` execution blocks.
40
+ - Run each block fail-fast, in order.
41
+ - Reuse the shared prelude before the first marker for every block.
42
+ - Pass the previous block output forward as `SHELLFLOW_LAST_OUTPUT`.
43
+ - Resolve remote targets from `~/.ssh/config` or a custom SSH config path.
44
+
45
+ ## Quick Start
46
+
47
+ ```bash
48
+ git clone https://github.com/longcipher/shellflow.git
49
+ cd shellflow
50
+ uv sync --all-groups # uv sync --refresh --reinstall --no-cache
51
+ uv tool install --force --reinstall --refresh --no-cache .
52
+
53
+ shellflow run playbooks/hello.sh
54
+ ```
55
+
56
+ If you do not want a global tool install, use `uv run shellflow run playbooks/hello.sh`.
57
+
58
+ ## Installation
59
+
60
+ ### Development checkout
61
+
62
+ ```bash
63
+ git clone https://github.com/longcipher/shellflow.git
64
+ cd shellflow
65
+ uv sync --all-groups # uv sync --refresh --reinstall --no-cache
66
+ ```
67
+
68
+ ### Install as a local tool
69
+
70
+ ```bash
71
+ uv tool install --force .
72
+ shellflow --version
73
+ ```
74
+
75
+ ### Install into the active environment
76
+
77
+ ```bash
78
+ uv pip install -e .
79
+ shellflow --version
80
+ ```
81
+
82
+ ## Script Format
83
+
84
+ Shellflow recognizes two markers:
85
+
86
+ - `# @LOCAL`
87
+ - `# @REMOTE <ssh-host>`
88
+
89
+ `<ssh-host>` must match a `Host` entry in your SSH config. Shellflow then connects using that SSH host definition, which means the actual machine can be resolved through the configured `HostName`, `User`, `Port`, and `IdentityFile` values.
90
+
91
+ Example:
92
+
93
+ ```bash
94
+ #!/bin/bash
95
+ set -euo pipefail
96
+
97
+ # @LOCAL
98
+ echo "runs locally"
99
+
100
+ # @REMOTE sui
101
+ uname -a
102
+
103
+ # @LOCAL
104
+ echo "remote output: $SHELLFLOW_LAST_OUTPUT"
105
+ ```
106
+
107
+ ## SSH Configuration
108
+
109
+ Example `~/.ssh/config` entry:
110
+
111
+ ```sshconfig
112
+ Host sui
113
+ HostName 192.168.1.100
114
+ User deploy
115
+ Port 22
116
+ IdentityFile ~/.ssh/id_ed25519
117
+ ```
118
+
119
+ With that config, this block is valid:
120
+
121
+ ```bash
122
+ # @REMOTE sui
123
+ hostname
124
+ ```
125
+
126
+ This is intentional:
127
+
128
+ - Shellflow accepts configured SSH host names, not arbitrary free-form targets.
129
+ - Unknown remote targets fail early with a clear error before spawning `ssh`.
130
+ - You can override the default config path with `--ssh-config`.
131
+
132
+ ## Execution Model
133
+
134
+ Each block runs in a fresh shell.
135
+
136
+ - Shell options from the prelude are copied into every block.
137
+ - Shell state like `cd`, shell variables, aliases, and `export` commands does not persist across blocks.
138
+ - Explicit context values are passed forward through environment variables.
139
+
140
+ Example:
141
+
142
+ ```bash
143
+ # @LOCAL
144
+ echo "build-123"
145
+
146
+ # @LOCAL
147
+ echo "last output = $SHELLFLOW_LAST_OUTPUT"
148
+ ```
149
+
150
+ Lines before the first marker are treated as a shared prelude and prepended to every executable block:
151
+
152
+ ```bash
153
+ #!/bin/bash
154
+ set -euo pipefail
155
+
156
+ # @LOCAL
157
+ echo "prelude is active"
158
+
159
+ # @REMOTE sui
160
+ echo "prelude is also active here"
161
+ ```
162
+
163
+ ## CLI
164
+
165
+ ```text
166
+ shellflow run <script>
167
+ shellflow run <script> --verbose
168
+ shellflow run <script> --ssh-config ./ssh_config
169
+ shellflow --version
170
+ ```
171
+
172
+ Examples:
173
+
174
+ ```bash
175
+ shellflow run playbooks/hello.sh
176
+ shellflow run playbooks/hello.sh -v
177
+ shellflow run playbooks/hello.sh --ssh-config ~/.ssh/config.work
178
+ ```
179
+
180
+ ## Development
181
+
182
+ Useful commands:
183
+
184
+ ```bash
185
+ just sync
186
+ just test
187
+ just bdd
188
+ just test-all
189
+ just typecheck
190
+ just build
191
+ just publish
192
+ ```
193
+
194
+ Direct verification commands:
195
+
196
+ ```bash
197
+ uv run pytest -q
198
+ uv run behave features
199
+ uv run ruff check .
200
+ uv run ty check src tests
201
+ uv build
202
+ ```
203
+
204
+ ## Release Process
205
+
206
+ Shellflow supports both local publishing and GitHub Actions release publishing.
207
+
208
+ ### Local publish
209
+
210
+ ```bash
211
+ just publish
212
+ ```
213
+
214
+ `uv publish` uses standard `uv` authentication mechanisms such as `UV_PUBLISH_TOKEN`, or PyPI trusted publishing when supported by the environment.
215
+
216
+ ### GitHub Actions publish on tag push
217
+
218
+ The repository includes:
219
+
220
+ - `.github/workflows/ci.yml` for lint, type-check, test, and build verification.
221
+ - `.github/workflows/release.yml` for publishing to PyPI when a tag like `v0.1.0` is pushed.
222
+
223
+ Recommended release flow:
224
+
225
+ ```bash
226
+ git tag v0.1.0
227
+ git push origin v0.1.0
228
+ ```
229
+
230
+ To use trusted publishing with PyPI:
231
+
232
+ 1. Create a `pypi` environment in GitHub repository settings.
233
+ 2. Add this repository as a trusted publisher in the PyPI project settings.
234
+ 3. Push a `v*` tag.
235
+
236
+ The release workflow then runs verification, builds distributions with `uv build`, and uploads them with `uv publish`.
237
+
238
+ ## Project Layout
239
+
240
+ ```text
241
+ shellflow/
242
+ ├── src/shellflow.py
243
+ ├── tests/
244
+ ├── features/
245
+ ├── playbooks/
246
+ ├── pyproject.toml
247
+ ├── Justfile
248
+ └── README.md
249
+ ```
250
+
251
+ ## License
252
+
253
+ Apache-2.0