devstuff 1.13.1__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 (53) hide show
  1. devstuff-1.13.1/.claude/skills/run-stuff/SKILL.md +65 -0
  2. devstuff-1.13.1/.claude/skills/run-stuff/smoke.sh +55 -0
  3. devstuff-1.13.1/.github/workflows/bump.yml +95 -0
  4. devstuff-1.13.1/.github/workflows/ci.yml +27 -0
  5. devstuff-1.13.1/.github/workflows/publish.yml +44 -0
  6. devstuff-1.13.1/.github/workflows/test-installs.yml +174 -0
  7. devstuff-1.13.1/.gitignore +11 -0
  8. devstuff-1.13.1/CHANGELOG.md +159 -0
  9. devstuff-1.13.1/CLAUDE.md +185 -0
  10. devstuff-1.13.1/PKG-INFO +617 -0
  11. devstuff-1.13.1/README.md +590 -0
  12. devstuff-1.13.1/dev/Dockerfile +38 -0
  13. devstuff-1.13.1/dev/Dockerfile.ci +17 -0
  14. devstuff-1.13.1/dev/Makefile +39 -0
  15. devstuff-1.13.1/dev/docker-compose.yml +14 -0
  16. devstuff-1.13.1/dev-setup +66 -0
  17. devstuff-1.13.1/install.sh +67 -0
  18. devstuff-1.13.1/pyproject.toml +75 -0
  19. devstuff-1.13.1/src/dev_setup/__init__.py +6 -0
  20. devstuff-1.13.1/src/dev_setup/__main__.py +9 -0
  21. devstuff-1.13.1/src/dev_setup/base.py +74 -0
  22. devstuff-1.13.1/src/dev_setup/catalog.py +188 -0
  23. devstuff-1.13.1/src/dev_setup/cli.py +49 -0
  24. devstuff-1.13.1/src/dev_setup/commands/__init__.py +0 -0
  25. devstuff-1.13.1/src/dev_setup/commands/add_cmd.py +334 -0
  26. devstuff-1.13.1/src/dev_setup/commands/catalog_cmd.py +37 -0
  27. devstuff-1.13.1/src/dev_setup/commands/delete_cmd.py +36 -0
  28. devstuff-1.13.1/src/dev_setup/commands/docs_cmd.py +34 -0
  29. devstuff-1.13.1/src/dev_setup/commands/functions_cmd.py +87 -0
  30. devstuff-1.13.1/src/dev_setup/commands/help_cmd.py +59 -0
  31. devstuff-1.13.1/src/dev_setup/commands/install_cmd.py +129 -0
  32. devstuff-1.13.1/src/dev_setup/commands/list_cmd.py +76 -0
  33. devstuff-1.13.1/src/dev_setup/commands/remove_cmd.py +53 -0
  34. devstuff-1.13.1/src/dev_setup/commands/run_cmd.py +66 -0
  35. devstuff-1.13.1/src/dev_setup/commands/update_cmd.py +149 -0
  36. devstuff-1.13.1/src/dev_setup/function_runner.py +133 -0
  37. devstuff-1.13.1/src/dev_setup/functions.schema.json +106 -0
  38. devstuff-1.13.1/src/dev_setup/functions.yaml +111 -0
  39. devstuff-1.13.1/src/dev_setup/functions_catalog.py +217 -0
  40. devstuff-1.13.1/src/dev_setup/functions_registry.py +149 -0
  41. devstuff-1.13.1/src/dev_setup/generic.py +719 -0
  42. devstuff-1.13.1/src/dev_setup/registry.py +97 -0
  43. devstuff-1.13.1/src/dev_setup/tools.yaml +679 -0
  44. devstuff-1.13.1/src/dev_setup/ui.py +111 -0
  45. devstuff-1.13.1/tests/__init__.py +0 -0
  46. devstuff-1.13.1/tests/integration/__init__.py +0 -0
  47. devstuff-1.13.1/tests/integration/conftest.py +5 -0
  48. devstuff-1.13.1/tests/integration/test_tools.py +50 -0
  49. devstuff-1.13.1/tests/test_catalog.py +159 -0
  50. devstuff-1.13.1/tests/test_functions.py +354 -0
  51. devstuff-1.13.1/tests/test_generic.py +161 -0
  52. devstuff-1.13.1/tests/test_registry.py +54 -0
  53. devstuff-1.13.1/uv.lock +577 -0
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: run-stuff
3
+ description: Run, build, test, and smoke-test the dev-setup CLI; exercise list/catalog/install commands
4
+ ---
5
+
6
+ `dev-setup` is a Python CLI that manages a Linux dev environment. It is driven directly via `uv run dev-setup <command>` — no GUI, no server, no browser. The smoke script at `.claude/skills/run-stuff/smoke.sh` is the primary agent harness.
7
+
8
+ ## Prerequisites
9
+
10
+ - Python 3.11+
11
+ - `uv` (installed at `~/.local/bin/uv`)
12
+
13
+ Install the package in editable mode once:
14
+
15
+ ```bash
16
+ uv pip install -e .
17
+ ```
18
+
19
+ ## Run (agent path)
20
+
21
+ Run the smoke script from the repo root:
22
+
23
+ ```bash
24
+ bash .claude/skills/run-stuff/smoke.sh
25
+ ```
26
+
27
+ It exercises `version`, `list` (all variants), `catalog path`, `catalog export`, and `--help`. Exits 0 on success, 1 on any failure.
28
+
29
+ To exercise a specific command directly:
30
+
31
+ ```bash
32
+ uv run dev-setup version
33
+ uv run dev-setup list
34
+ uv run dev-setup list core
35
+ uv run dev-setup list --installed
36
+ uv run dev-setup list --available
37
+ uv run dev-setup catalog path
38
+ uv run dev-setup catalog export /tmp/export.yaml
39
+ uv run dev-setup --help
40
+ ```
41
+
42
+ Interactive commands (`install`, `remove`, `add`, `delete`) require a TTY and are not smoke-testable without mocking. To test them, run the app directly in a terminal.
43
+
44
+ ## Run (human path)
45
+
46
+ ```bash
47
+ ./dev-setup list # bash wrapper — bootstraps .venv on first run
48
+ ./dev-setup install # interactive multi-select picker
49
+ ```
50
+
51
+ ## Test suite
52
+
53
+ ```bash
54
+ uv run pytest # unit tests only (integration tests skipped by default)
55
+ uv run pytest -m integration # real installs — requires sudo + network
56
+ ```
57
+
58
+ All 6 unit tests pass in ~0.3s.
59
+
60
+ ## Gotchas
61
+
62
+ - `dev-setup` is not on `$PATH` directly in the dev environment — `uv run dev-setup` is the reliable invocation path. The `./dev-setup` bash wrapper also works from repo root and bootstraps its own `.venv`.
63
+ - `pip` is not available in this environment; `uv pip install` is the substitute.
64
+ - Interactive commands (`install`, `add`) open questionary/click prompts that hang in non-TTY shells. Pipe input only if you know the exact prompt sequence.
65
+ - `catalog export` writes to a path argument; without an argument it prints to stdout. Check the README for the exact signature.
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env bash
2
+ # Smoke test for dev-setup CLI. Run from repo root.
3
+ set -euo pipefail
4
+
5
+ PASS=0
6
+ FAIL=0
7
+
8
+ check() {
9
+ local label="$1"; shift
10
+ if output=$("$@" 2>&1); then
11
+ echo " ✔ $label"
12
+ PASS=$((PASS+1))
13
+ else
14
+ echo " ✘ $label"
15
+ echo " Output: $output"
16
+ FAIL=$((FAIL+1))
17
+ fi
18
+ }
19
+
20
+ check_output() {
21
+ local label="$1"; local expected="$2"; shift 2
22
+ output=$("$@" 2>&1)
23
+ if echo "$output" | grep -q "$expected"; then
24
+ echo " ✔ $label"
25
+ PASS=$((PASS+1))
26
+ else
27
+ echo " ✘ $label (expected '$expected' in output)"
28
+ echo " Got: $output"
29
+ FAIL=$((FAIL+1))
30
+ fi
31
+ }
32
+
33
+ echo ""
34
+ echo "=== dev-setup smoke tests ==="
35
+ echo ""
36
+
37
+ check "version" uv run dev-setup version
38
+ check_output "version number" "1\." uv run dev-setup version
39
+ check "list (all)" uv run dev-setup list
40
+ check "list core" uv run dev-setup list core
41
+ check "list tools" uv run dev-setup list tools
42
+ check "list --installed" uv run dev-setup list --installed
43
+ check "list --available" uv run dev-setup list --available
44
+ check "catalog path" uv run dev-setup catalog path
45
+ check_output "catalog path output" ".config/dev-setup" uv run dev-setup catalog path
46
+ check "catalog export" uv run dev-setup catalog export /tmp/dev-setup-smoke-export.yaml
47
+ check_output "help flag" "Commands:" uv run dev-setup --help
48
+
49
+ echo ""
50
+ if [ "$FAIL" -eq 0 ]; then
51
+ echo "All $PASS checks passed."
52
+ else
53
+ echo "$FAIL/$((PASS+FAIL)) checks failed."
54
+ exit 1
55
+ fi
@@ -0,0 +1,95 @@
1
+ name: Bump version
2
+
3
+ on:
4
+ pull_request:
5
+ types: [closed]
6
+ branches:
7
+ - master
8
+
9
+ # Serialize bump runs against master regardless of which PR triggered them.
10
+ concurrency:
11
+ group: bump-master
12
+ cancel-in-progress: false
13
+
14
+ jobs:
15
+ bump:
16
+ name: cz bump
17
+ runs-on: ubuntu-latest
18
+ # Only run for PRs that were actually merged, not closed unmerged.
19
+ # A raw `git push` — which is how this job publishes its own commit —
20
+ # never fires pull_request events, so there's no infinite-loop risk
21
+ # from this job triggering itself (unlike the old push-to-master
22
+ # trigger, which needed an explicit "bump:" message guard for that).
23
+ if: github.event.pull_request.merged == true
24
+ permissions:
25
+ contents: write
26
+ env:
27
+ # secrets can't be referenced directly in step `if:` conditions, so
28
+ # surface presence via an env var instead.
29
+ HAS_GH_PAT: ${{ secrets.GH_PAT != '' }}
30
+
31
+ steps:
32
+ - name: Require GH_PAT
33
+ # GH_PAT (a Personal Access Token with repo write scope) is required
34
+ # so that the tag push re-triggers publish.yml — GitHub Actions does
35
+ # not re-process events from pushes made with GITHUB_TOKEN. Fail loudly
36
+ # instead of silently pushing a tag that will never publish.
37
+ if: env.HAS_GH_PAT != 'true'
38
+ run: |
39
+ echo "::error::GH_PAT secret is not set. It is required so the tag push triggers publish.yml (GITHUB_TOKEN pushes are not re-processed by Actions)."
40
+ exit 1
41
+
42
+ - uses: actions/checkout@v4
43
+ with:
44
+ ref: master # the merge already happened server-side by the time this runs
45
+ fetch-depth: 0 # commitizen needs full history to determine bump type
46
+ token: ${{ secrets.GH_PAT }}
47
+
48
+ - name: Install uv
49
+ uses: astral-sh/setup-uv@v5
50
+
51
+ - name: Configure git
52
+ run: |
53
+ git config user.name "github-actions[bot]"
54
+ git config user.email "github-actions[bot]@users.noreply.github.com"
55
+
56
+ - name: Run cz bump
57
+ id: bump
58
+ run: |
59
+ if uv run --group dev cz bump --yes; then
60
+ echo "bumped=true" >> "$GITHUB_OUTPUT"
61
+ else
62
+ EXIT=$?
63
+ if [ "$EXIT" -eq 21 ]; then
64
+ echo "No conventional commits found since last tag — nothing to bump."
65
+ echo "bumped=false" >> "$GITHUB_OUTPUT"
66
+ else
67
+ exit "$EXIT"
68
+ fi
69
+ fi
70
+
71
+ - name: Sync lockfile
72
+ if: steps.bump.outputs.bumped == 'true'
73
+ run: |
74
+ uv lock
75
+ git add uv.lock
76
+ if ! git diff --staged --quiet; then
77
+ # cz bump already tagged the pre-lock commit; amending moves HEAD
78
+ # to a new SHA, so the tag must be recreated to point at it.
79
+ # Must stay annotated (-a) — `git push --follow-tags` only
80
+ # pushes annotated tags, so a lightweight retag here would
81
+ # silently never reach the remote.
82
+ tag="$(git describe --tags --exact-match HEAD)"
83
+ git commit --amend --no-edit
84
+ git tag -f -a "$tag" -m "$tag" HEAD
85
+ fi
86
+
87
+ - name: Push commit and tag
88
+ if: steps.bump.outputs.bumped == 'true'
89
+ run: |
90
+ git push --follow-tags
91
+ tag="$(git describe --tags --exact-match HEAD)"
92
+ if ! git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null; then
93
+ echo "::error::${tag} was not found on origin after push --follow-tags (publish.yml will not trigger)."
94
+ exit 1
95
+ fi
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ name: Lint & unit tests
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: read
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: astral-sh/setup-uv@v5
19
+
20
+ - name: Sync dependencies
21
+ run: uv sync
22
+
23
+ - name: Ruff lint
24
+ run: uv run ruff check .
25
+
26
+ - name: Unit tests
27
+ run: uv run pytest -v
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ name: Build distribution
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v5
17
+
18
+ - name: Build wheel and source distribution
19
+ run: uv build
20
+
21
+ - name: Upload dist artifacts
22
+ uses: actions/upload-artifact@v4
23
+ with:
24
+ name: dist
25
+ path: dist/
26
+
27
+ publish:
28
+ name: Publish to PyPI
29
+ needs: build
30
+ runs-on: ubuntu-latest
31
+ environment:
32
+ name: pypi
33
+ url: https://pypi.org/p/devstuff
34
+ permissions:
35
+ id-token: write # required for OIDC trusted publishing
36
+ steps:
37
+ - name: Download dist artifacts
38
+ uses: actions/download-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+
43
+ - name: Publish to PyPI
44
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,174 @@
1
+ name: Integration — Tool Installation
2
+
3
+ # Weekly canary: catches upstream breakage (changed download URLs, API changes, etc.)
4
+ # Manual trigger for ad-hoc validation (e.g., after merging a new tool).
5
+ on:
6
+ schedule:
7
+ - cron: "0 6 * * 1" # Monday 06:00 UTC
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ # ─── Stage 1: build the test image once and share it across all matrix jobs ───
12
+ build:
13
+ name: Build CI test image
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ contents: read
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: astral-sh/setup-uv@v5
22
+
23
+ - name: Build wheel
24
+ run: uv build
25
+
26
+ # Two-step docker build matching the local dev workflow:
27
+ # dev/Dockerfile → dev-setup-sandbox (minimal system + wheel installed)
28
+ # dev/Dockerfile.ci → dev-setup-ci (+ pytest + test files baked in)
29
+ - name: Build sandbox image
30
+ run: docker build -f dev/Dockerfile -t dev-setup-sandbox .
31
+
32
+ - name: Build CI test image
33
+ run: docker build -f dev/Dockerfile.ci -t dev-setup-ci .
34
+
35
+ - name: Export image archive
36
+ run: docker save dev-setup-ci | gzip > dev-setup-ci.tar.gz
37
+
38
+ - name: Upload image artifact
39
+ uses: actions/upload-artifact@v4
40
+ with:
41
+ name: docker-image
42
+ path: dev-setup-ci.tar.gz
43
+ retention-days: 1
44
+
45
+ # ─── Stage 2: one isolated container per tool, all run in parallel ───────────
46
+ test:
47
+ name: Test — ${{ matrix.tool }}
48
+ needs: build
49
+ runs-on: ubuntu-latest
50
+ strategy:
51
+ fail-fast: false # let all tools run even when some fail
52
+ matrix:
53
+ tool:
54
+ - aws
55
+ - eza
56
+ - gh
57
+ - git-lfs
58
+ - go
59
+ - htop
60
+ - ipython # uvx tool, requires uv
61
+ - java
62
+ - lazygit
63
+ - mkcert
64
+ - nvm
65
+ - php
66
+ - pi # installs nvm first via its declared `requires`
67
+ - ruby # compiles from source — this job takes ~15 minutes
68
+ - saml2aws
69
+ - starship
70
+ - uv
71
+ - whichllm # uvx tool, requires uv
72
+ - yq
73
+
74
+ steps:
75
+ - name: Download image artifact
76
+ uses: actions/download-artifact@v4
77
+ with:
78
+ name: docker-image
79
+
80
+ - name: Load image
81
+ run: docker load < dev-setup-ci.tar.gz
82
+
83
+ - name: Test ${{ matrix.tool }} installs
84
+ run: |
85
+ set +e
86
+ docker run --rm dev-setup-ci \
87
+ pytest "tests/integration/test_tools.py::test_install[${{ matrix.tool }}]" \
88
+ -v --tb=short 2>&1 | tee test-output.txt
89
+ RESULT=${PIPESTATUS[0]}
90
+ exit ${RESULT}
91
+
92
+ - name: Upload test output
93
+ if: always()
94
+ uses: actions/upload-artifact@v4
95
+ with:
96
+ name: test-output-${{ matrix.tool }}
97
+ path: test-output.txt
98
+
99
+ # Failure marker: a tiny file named after the tool so the report job can
100
+ # list exactly which tools failed without parsing pytest output.
101
+ - name: Write failure marker
102
+ if: failure()
103
+ run: echo "${{ matrix.tool }}" > "${{ matrix.tool }}.txt"
104
+
105
+ - name: Upload failure marker
106
+ if: failure()
107
+ uses: actions/upload-artifact@v4
108
+ with:
109
+ name: failure-${{ matrix.tool }}
110
+ path: ${{ matrix.tool }}.txt
111
+
112
+ # ─── Stage 3: open or update one GitHub issue summarising all failures ────────
113
+ report:
114
+ name: Report failures
115
+ needs: test
116
+ if: always() && needs.test.result == 'failure'
117
+ runs-on: ubuntu-latest
118
+ permissions:
119
+ contents: read
120
+ issues: write
121
+
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+
125
+ - name: Download failure markers
126
+ uses: actions/download-artifact@v4
127
+ with:
128
+ pattern: failure-*
129
+ merge-multiple: true
130
+ path: failures/
131
+ continue-on-error: true # no artifacts = nothing to download; don't abort
132
+
133
+ - name: Create or update issue
134
+ env:
135
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
136
+ RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
137
+ run: |
138
+ # Collect the names of tools that failed from their marker files
139
+ FAILED_LIST=""
140
+ for f in failures/*.txt; do
141
+ [ -f "$f" ] || continue
142
+ FAILED_LIST="${FAILED_LIST}\n- $(cat "$f")"
143
+ done
144
+
145
+ if [ -z "$FAILED_LIST" ]; then
146
+ FAILED_LIST="\n- (unknown — inspect the workflow run for details)"
147
+ fi
148
+
149
+ # Ensure the tracking label exists (no-ops if already present)
150
+ gh label create "install-ci" \
151
+ --color "#e11d48" \
152
+ --description "Automated tool-installation CI failure" \
153
+ 2>/dev/null || true
154
+
155
+ BODY="## Tool installation failures\n\nThe following builtin tools failed to install in a clean Ubuntu environment:\n${FAILED_LIST}\n\n**Workflow run:** ${RUN_URL}\n\n_Opened automatically by the \`test-installs\` workflow. Close this issue once the failure is resolved and confirmed passing._"
156
+
157
+ # Dedup: comment on the existing open issue rather than filing a new one.
158
+ # This keeps the tracker tidy across weekly runs.
159
+ EXISTING=$(gh issue list \
160
+ --label "install-ci" \
161
+ --state open \
162
+ --json number \
163
+ --jq '.[0].number' 2>/dev/null)
164
+
165
+ if [ -n "$EXISTING" ]; then
166
+ gh issue comment "${EXISTING}" \
167
+ --body "$(printf '%b' "${BODY}")"
168
+ echo "Commented on existing issue #${EXISTING}"
169
+ else
170
+ gh issue create \
171
+ --title "Install CI: tool failures ($(date +%Y-%m-%d))" \
172
+ --body "$(printf '%b' "${BODY}")" \
173
+ --label "install-ci,bug"
174
+ fi
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .claude/settings.local.json
@@ -0,0 +1,159 @@
1
+ ## v1.13.1 (2026-07-11)
2
+
3
+ ## v1.13.0 (2026-07-05)
4
+
5
+ ### Feat
6
+
7
+ - add category field, yq tool, and 4 new functions
8
+
9
+ ## v1.12.0 (2026-07-05)
10
+
11
+ ### Feat
12
+
13
+ - add functions/scripts subsystem (dev-setup run / functions)
14
+
15
+ ### Fix
16
+
17
+ - enforce required function params — empty values and bashrc calls
18
+
19
+ ## v1.11.0 (2026-07-05)
20
+
21
+ ### Feat
22
+
23
+ - add interactive update picker with recommended-update detection
24
+ - add update command to upgrade installed packages
25
+ - add CLAUDE.md for project guidance and tool installation instructions
26
+ - group interactive install picker by category with aligned columns and parallel status probe
27
+
28
+ ### Refactor
29
+
30
+ - dataclass GenericTool with strategy dispatch, recursive requires, sha256 script verification, parallel list, ruff lint + unit tests
31
+
32
+ ## v1.10.0 (2026-07-04)
33
+
34
+ ### Feat
35
+
36
+ - **catalog**: add ansible and ansible-vault tools
37
+
38
+ ## v1.9.1 (2026-07-01)
39
+
40
+ ### Fix
41
+
42
+ - correct lmstudio tool entry and add homebrew
43
+
44
+ ## v1.9.0 (2026-07-01)
45
+
46
+ ### Feat
47
+
48
+ - remove eza tool and update llm-checker configuration in tools.yaml
49
+
50
+ ## v1.8.2 (2026-07-01)
51
+
52
+ ### Fix
53
+
54
+ - bump workflow silently dropped the tag after lockfile sync
55
+
56
+ ## v1.8.1 (2026-07-01)
57
+
58
+ ### Fix
59
+
60
+ - move GH_PAT presence check out of step if: condition
61
+ - harden bump workflow and close CI/removal gaps found in review
62
+
63
+ ## v1.8.0 (2026-06-28)
64
+
65
+ ### Feat
66
+
67
+ - **catalog**: add ipython to tools
68
+ - add bat and pre-commit to tool catalog
69
+
70
+ ### Fix
71
+
72
+ - update git push command to ensure tags are pushed correctly
73
+ - update Pi Coding Agent tool configuration for improved installation and usage
74
+ - enhance Makefile with run-tests options for improved testing flexibility
75
+ - remove legacy migration and correct YAML refactor bugs
76
+
77
+ ## v1.7.1 (2026-06-27)
78
+
79
+ ### Fix
80
+
81
+ - include whichllm and corrected uv.lock
82
+
83
+ ## v1.7.0 (2026-06-27)
84
+
85
+ ### Feat
86
+
87
+ - load tools from YAML catalogs
88
+
89
+ ## v1.6.0 (2026-06-26)
90
+
91
+ ### Feat
92
+
93
+ - update add_cmd to support uvx package type and enhance GenericTool for uv dependencies
94
+
95
+ ## v1.5.0 (2026-06-26)
96
+
97
+ ### Feat
98
+
99
+ - post-add remove script validation for bash tools
100
+
101
+ ### Fix
102
+
103
+ - restore zip permissions explicitly and surface aws installer errors
104
+ - resolve CI install failures for aws, htop, php, ruby
105
+
106
+ ## v1.4.0 (2026-06-19)
107
+
108
+ ### Feat
109
+
110
+ - add eza builtin tool
111
+
112
+ ## v1.3.0 (2026-06-19)
113
+
114
+ ### Feat
115
+
116
+ - gate tool availability on required dependencies
117
+
118
+ ## v1.2.0 (2026-06-19)
119
+
120
+ ### Feat
121
+
122
+ - add docker-compose.yml to dev/ sandbox
123
+ - add dev/ sandbox with Dockerfile for local install testing
124
+ - add docs command to open tool documentation in the browser
125
+ - add Go, Java, and Ruby builtin tools under languages category
126
+ - add gh, mkcert, ollama, and pi-coding-agent builtin tools
127
+ - add --verbose/-v flag to stream install/remove output
128
+
129
+ ### Docs
130
+
131
+ - add Prerequisites section to README
132
+
133
+ ### Chore
134
+
135
+ - add commitizen dev dep and unify version source
136
+
137
+ ## v1.1.0 (2026-06-18)
138
+
139
+ ### Feat
140
+
141
+ - add aws-cli and saml2aws built-in packages
142
+ - add bash type for multi-step custom installs
143
+ - add help_cmd field to all tools, display in list output
144
+ - enhance project metadata in pyproject.toml
145
+
146
+ ### Refactor
147
+
148
+ - improve maintainability and extensibility for new tool additions
149
+ - switch from uv-run to pip/pipx install pattern
150
+
151
+ ### Docs
152
+
153
+ - add comprehensive README
154
+
155
+ ## v1.0.0 (2026-06-17)
156
+
157
+ ### Feat
158
+
159
+ - initial Python implementation of dev-setup CLI