code-aide 1.15.0__tar.gz → 1.15.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 (65) hide show
  1. {code_aide-1.15.0 → code_aide-1.15.2}/AGENTS.md +22 -16
  2. code_aide-1.15.2/PKG-INFO +201 -0
  3. code_aide-1.15.2/README.md +174 -0
  4. {code_aide-1.15.0 → code_aide-1.15.2}/TODO.md +14 -16
  5. {code_aide-1.15.0 → code_aide-1.15.2}/pyproject.toml +16 -0
  6. {code_aide-1.15.0 → code_aide-1.15.2}/script-archive/amp-install.sh +0 -8
  7. {code_aide-1.15.0 → code_aide-1.15.2}/script-archive/claude-install.sh +7 -0
  8. code_aide-1.15.2/specs/2026-05-03-qwen3.6-code-quality-analysis-original.md +196 -0
  9. code_aide-1.15.2/specs/2026-05-03-qwen3.6-code-quality-analysis.md +296 -0
  10. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/__init__.py +1 -1
  11. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/commands_tools.py +7 -6
  12. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/config.py +15 -6
  13. code_aide-1.15.2/src/code_aide/console.py +62 -0
  14. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/constants.py +12 -3
  15. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/data/tools.json +2 -2
  16. code_aide-1.15.2/src/code_aide/detection.py +236 -0
  17. code_aide-1.15.2/src/code_aide/detection_types.py +26 -0
  18. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/entry.py +22 -0
  19. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/install.py +3 -1
  20. code_aide-1.15.2/src/code_aide/operation_handlers.py +240 -0
  21. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/operations.py +21 -196
  22. code_aide-1.15.0/src/code_aide/detection.py → code_aide-1.15.2/src/code_aide/package_info.py +30 -218
  23. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/prereqs.py +1 -1
  24. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/status.py +15 -122
  25. code_aide-1.15.2/src/code_aide/status_print.py +126 -0
  26. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/versions.py +1 -1
  27. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_commands_actions.py +6 -6
  28. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_commands_tools.py +8 -8
  29. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_console.py +9 -3
  30. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_detection.py +20 -19
  31. code_aide-1.15.2/tests/test_entry.py +105 -0
  32. code_aide-1.15.2/tests/test_error_paths.py +332 -0
  33. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_install.py +8 -8
  34. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_operations.py +21 -20
  35. code_aide-1.15.2/tests/test_prereqs.py +253 -0
  36. code_aide-1.15.2/uv.lock +381 -0
  37. code_aide-1.15.0/PKG-INFO +0 -174
  38. code_aide-1.15.0/README.md +0 -147
  39. code_aide-1.15.0/src/code_aide/console.py +0 -58
  40. code_aide-1.15.0/uv.lock +0 -243
  41. {code_aide-1.15.0 → code_aide-1.15.2}/.github/workflows/ci.yml +0 -0
  42. {code_aide-1.15.0 → code_aide-1.15.2}/.github/workflows/publish.yml +0 -0
  43. {code_aide-1.15.0 → code_aide-1.15.2}/.gitignore +0 -0
  44. {code_aide-1.15.0 → code_aide-1.15.2}/.gitlab-ci.yml +0 -0
  45. {code_aide-1.15.0 → code_aide-1.15.2}/.pre-commit-config.yaml +0 -0
  46. {code_aide-1.15.0 → code_aide-1.15.2}/CLAUDE.md +0 -0
  47. {code_aide-1.15.0 → code_aide-1.15.2}/LICENSE +0 -0
  48. {code_aide-1.15.0 → code_aide-1.15.2}/script-archive/README.md +0 -0
  49. {code_aide-1.15.0 → code_aide-1.15.2}/script-archive/cursor-install.sh +0 -0
  50. {code_aide-1.15.0 → code_aide-1.15.2}/specs/auto-migrate-deprecated-installs.md +0 -0
  51. {code_aide-1.15.0 → code_aide-1.15.2}/specs/claude-native-installer-migration.md +0 -0
  52. {code_aide-1.15.0 → code_aide-1.15.2}/specs/missing-coding-llm-cli-tools.md +0 -0
  53. {code_aide-1.15.0 → code_aide-1.15.2}/specs/pre-commit-uv-setup.md +0 -0
  54. {code_aide-1.15.0 → code_aide-1.15.2}/specs/remove-bundled-version-baseline.md +0 -0
  55. {code_aide-1.15.0 → code_aide-1.15.2}/specs/unify-upgrade-eligibility-with-shared-evaluator.md +0 -0
  56. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/__main__.py +0 -0
  57. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/commands_actions.py +0 -0
  58. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/install_types.py +0 -0
  59. {code_aide-1.15.0 → code_aide-1.15.2}/src/code_aide/package_managers.py +0 -0
  60. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_config.py +0 -0
  61. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_constants.py +0 -0
  62. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_install_types.py +0 -0
  63. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_package_managers.py +0 -0
  64. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_status.py +0 -0
  65. {code_aide-1.15.0 → code_aide-1.15.2}/tests/test_versions.py +0 -0
@@ -5,28 +5,34 @@
5
5
 
6
6
  ## Key Design Decisions
7
7
 
8
- - Runtime dependencies are stdlib only (`dependencies` in pyproject.toml).
9
- Dev tooling (pytest, black, ruff) lives in `dependency-groups` for tests
10
- and linting.
8
+ - Runtime dependencies are stdlib only (`dependencies` in pyproject.toml). Dev
9
+ tooling (pytest, black, ruff) lives in `dependency-groups` for tests and
10
+ linting.
11
11
  - Primary supported environments are macOS and Linux (see pyproject
12
- classifiers); avoid assuming Windows-specific behavior unless explicitly
13
- in scope.
14
- - For planned behavior or refactors, read matching notes under `specs/`
15
- before inventing design.
16
- - Two-layer version data: bundled definitions (with SHA256 checksums),
17
- user's local cache (~/.config/code-aide/versions.json)
12
+ classifiers); avoid assuming Windows-specific behavior unless explicitly in
13
+ scope.
14
+ - For planned behavior or refactors, read matching notes under `specs/` before
15
+ inventing design.
16
+ - Two-layer version data: bundled definitions (with SHA256 checksums), user's
17
+ local cache (~/.config/code-aide/versions.json)
18
+ - Third-party install scripts are archived under `script-archive/` and their
19
+ SHA256 hashes are stored in `src/code_aide/data/tools.json`
20
+ (`install_sha256`). When an upgrade reports a SHA256 mismatch: (1) download
21
+ the new script to a temp file, (2) `diff script-archive/<tool>-install.sh
22
+ /tmp/new-script.sh` and review every change for anything suspicious, (3) if
23
+ safe, copy the new script over the archive copy and update `install_sha256` in
24
+ `tools.json`, (4) commit both files together. See `script-archive/README.md`
25
+ for the full procedure.
18
26
  - All tests should pass before committing
19
27
  - pre-commit runs black and ruff on commit; run `black` to format and then
20
28
  `pre-commit run --all-files` to check before committing
21
- - When changing pyproject.toml dependencies, run `uv lock` and commit
22
- uv.lock
29
+ - When changing pyproject.toml dependencies, run `uv lock` and commit uv.lock
23
30
  - Write useful commit messages: start subjects with past-tense action verbs
24
31
  (`Added`, `Changed`, `Fixed`, `Removed`), keep them user-facing, and keep
25
32
  commits focused.
26
33
  - Python 3.11+ compatible
27
34
  - Keep files under 300 lines where practical
28
- - Run `format-markdown` on markdown files before commits (if it is
29
- available)
30
- - When pushing tags, always push them explicitly with `git push <remote>
31
- <tag>` rather than relying on `--follow-tags`, which silently skips tags
32
- when the branch commits are already on the remote
35
+ - Run `format-markdown` on markdown files before commits (if it is available)
36
+ - When pushing tags, always push them explicitly with `git push <remote> <tag>`
37
+ rather than relying on `--follow-tags`, which silently skips tags when the
38
+ branch commits are already on the remote
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: code-aide
3
+ Version: 1.15.2
4
+ Summary: Manage AI coding CLI tools (Claude, Copilot, Cursor, Gemini, Amp, Codex)
5
+ Project-URL: Homepage, https://github.com/dajobe/code-aide
6
+ Project-URL: Repository, https://github.com/dajobe/code-aide
7
+ Project-URL: Issues, https://github.com/dajobe/code-aide/issues
8
+ Project-URL: Changelog, https://github.com/dajobe/code-aide/releases
9
+ Author: Dave Beckett
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX :: BSD :: FreeBSD
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development :: Build Tools
24
+ Classifier: Topic :: System :: Installation/Setup
25
+ Requires-Python: >=3.11
26
+ Description-Content-Type: text/markdown
27
+
28
+ # code-aide
29
+
30
+ An aide for your AI coding tools.
31
+
32
+ Manages installation, upgrade, removal, and version tracking of AI coding CLI
33
+ tools: Claude Code, Copilot, Cursor, Gemini, Amp, Codex, OpenCode, and Kilo.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ # Run without installing (requires uv)
39
+ uvx code-aide status
40
+
41
+ # Install persistently
42
+ uv tool install code-aide
43
+
44
+ # Or use pipx
45
+ pipx install code-aide
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ```bash
51
+ # List available tools and their status
52
+ code-aide list
53
+
54
+ # Show compact one-line-per-tool status
55
+ code-aide status
56
+
57
+ # Show detailed status for installed tools
58
+ code-aide status -l
59
+
60
+ # Install specific tools
61
+ code-aide install claude gemini
62
+
63
+ # Install all default tools
64
+ code-aide install
65
+
66
+ # Install with automatic prerequisite installation (Node.js, npm)
67
+ code-aide install -p
68
+
69
+ # Upgrade installed tools (no args = only out-of-date tools)
70
+ code-aide upgrade [NAMES]
71
+
72
+ # Remove tools
73
+ code-aide remove [NAMES]
74
+
75
+ # Check upstream for latest versions (dry-run)
76
+ code-aide update-versions -n
77
+
78
+ # Update version cache
79
+ code-aide update-versions -y
80
+ ```
81
+
82
+ ## Supported Tools
83
+
84
+ | Tool | Command | Install Type | Default |
85
+ |:-------------------------|:-----------|:----------------|:--------|
86
+ | Cursor CLI | `agent` | Direct download | Yes |
87
+ | Claude CLI (Claude Code) | `claude` | Script | Yes |
88
+ | Gemini CLI | `gemini` | npm | Yes |
89
+ | OpenCode | `opencode` | npm | No |
90
+ | Kilo CLI | `kilo` | npm | No |
91
+ | Amp (Sourcegraph) | `amp` | Script | No |
92
+ | Codex CLI | `codex` | npm | No |
93
+ | Copilot CLI | `copilot` | npm | No |
94
+
95
+ ## How Version Data Works
96
+
97
+ code-aide uses a two-layer version data model:
98
+
99
+ 1. **Bundled tool definitions** (in `data/tools.json`): Install methods, URLs,
100
+ npm packages, version args, and SHA256 checksums. Updated by releasing new
101
+ versions of code-aide.
102
+
103
+ 2. **User's local version cache** (`~/.config/code-aide/versions.json`): Written
104
+ by `code-aide update-versions`. Provides latest versions, dates, and updated
105
+ SHA256 checksums.
106
+
107
+ Run `code-aide update-versions` to get the latest version data without waiting
108
+ for a new code-aide release.
109
+
110
+ ## Tool definition schema (`data/tools.json`)
111
+
112
+ Each entry in `tools.json` describes one managed tool. Required fields are
113
+ `name`, `command`, and `install_type`; the others are optional and only
114
+ consulted when the relevant install method or platform applies.
115
+
116
+ | Field | Required | Notes |
117
+ |:------------------------------|:---------|:---------------------------------------------------------------------------------------------|
118
+ | `name` | Yes | Display name for status output |
119
+ | `command` | Yes | Binary name (looked up in `PATH`) |
120
+ | `install_type` | Yes | One of `npm`, `script`, `direct_download`, `pkg` |
121
+ | `version_args` | No | List of arguments passed to the binary to print its version (default: `["--version"]`) |
122
+ | `version_url` | No | URL queried by `update-versions` to discover the latest upstream version |
123
+ | `latest_version` | Cache | Last known upstream version (filled by `update-versions`) |
124
+ | `latest_date` | Cache | Release date for `latest_version` |
125
+ | `prerequisites` | No | List of required external commands (e.g. `["npm"]`) |
126
+ | `min_node_version` | No | Minimum major Node.js version required |
127
+ | `npm_package` | npm | npm package name (e.g. `@anthropic-ai/claude-code`) |
128
+ | `install_url` | script | URL of the install script that will be downloaded and piped to `bash` |
129
+ | `install_sha256` | script | SHA-256 of the install script body — required for verified installs |
130
+ | `install_script_path_prepend` | script | Extra directories prepended to `PATH` when the install script runs (e.g. `["~/.local/bin"]`) |
131
+ | `download_url_template` | direct | URL template with `{version}`, `{os}`, `{arch}` placeholders |
132
+ | `install_dir` | direct | Directory to extract into; supports `{version}` |
133
+ | `bin_dir` | direct | Directory where symlinks for `command` are created (e.g. `~/.local/bin`) |
134
+ | `symlinks` | direct | Map of `link_name` → relative path inside `install_dir` to symlink into `bin_dir` |
135
+ | `freebsd_port` | FreeBSD | FreeBSD ports/pkg name (used when running on FreeBSD) |
136
+ | `freebsd_pkg_repo` | FreeBSD | Optional non-default pkg repository name (passed via `pkg install -r <repo>`) |
137
+ | `next_steps` | No | Free-form text printed after a successful install |
138
+ | `docs_url` | No | Documentation URL printed after install |
139
+
140
+ ## Features
141
+
142
+ - Zero external dependencies (Python stdlib only)
143
+ - SHA256 verification for script-based installations
144
+ - Automatic prerequisite detection and installation (Node.js, npm)
145
+ - Detects install method (Homebrew, npm, system package, script, direct
146
+ download)
147
+ - PATH configuration validation and warnings
148
+ - Supports Linux and macOS
149
+
150
+ ## Requirements
151
+
152
+ - Python 3.11+
153
+ - No external Python dependencies
154
+
155
+ ## Development
156
+
157
+ 1. Install uv: `curl -LsSf https://astral.sh/uv/install.sh | sh`
158
+ 2. Install dependencies: `uv sync`
159
+ 3. Install pre-commit hooks: `uv tool install pre-commit && pre-commit install`
160
+ 4. Run tests: `uv run pytest tests/ -v`
161
+
162
+ ```bash
163
+ # Run from development checkout
164
+ uv run python -m code_aide status
165
+ uv run python -m code_aide install copilot
166
+
167
+ # Run a specific test
168
+ uv run pytest tests/test_install.py::TestDetectOsArch -v
169
+ ```
170
+
171
+ ## Release
172
+
173
+ `publish.yml` publishes to PyPI when a Git tag matching `v*` is pushed.
174
+
175
+ 1. Update the version string in `src/code_aide/__init__.py` (`__version__`).
176
+ `pyproject.toml` reads it automatically via Hatchling.
177
+ 2. Run checks:
178
+ - `uv run pytest tests/ -v`
179
+ - `uv build`
180
+ 3. Commit the release version bump:
181
+ - `git add src/code_aide/__init__.py`
182
+ - `git commit -m "Bumped version to X.Y.Z"`
183
+ 4. Write useful commit messages before tagging:
184
+ - Start subject lines with an action verb in past tense (`Added`, `Changed`,
185
+ `Fixed`, `Removed`).
186
+ - Keep subjects user-facing so auto-generated release notes are meaningful.
187
+ - Group related changes into focused commits instead of one broad commit.
188
+ - Example: `Fixed timeout handling in status command`
189
+ 5. Tag and push:
190
+ - `git tag vX.Y.Z`
191
+ - `git push origin main`
192
+ - `git push origin vX.Y.Z`
193
+ 6. Confirm GitHub Actions:
194
+ - CI should pass.
195
+ - Publish workflow should upload to PyPI and create GitHub Release notes.
196
+ - Release notes should include generated notes plus a commit summary from the
197
+ previous tag to the current tag.
198
+
199
+ ## License
200
+
201
+ Apache-2.0
@@ -0,0 +1,174 @@
1
+ # code-aide
2
+
3
+ An aide for your AI coding tools.
4
+
5
+ Manages installation, upgrade, removal, and version tracking of AI coding CLI
6
+ tools: Claude Code, Copilot, Cursor, Gemini, Amp, Codex, OpenCode, and Kilo.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ # Run without installing (requires uv)
12
+ uvx code-aide status
13
+
14
+ # Install persistently
15
+ uv tool install code-aide
16
+
17
+ # Or use pipx
18
+ pipx install code-aide
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ # List available tools and their status
25
+ code-aide list
26
+
27
+ # Show compact one-line-per-tool status
28
+ code-aide status
29
+
30
+ # Show detailed status for installed tools
31
+ code-aide status -l
32
+
33
+ # Install specific tools
34
+ code-aide install claude gemini
35
+
36
+ # Install all default tools
37
+ code-aide install
38
+
39
+ # Install with automatic prerequisite installation (Node.js, npm)
40
+ code-aide install -p
41
+
42
+ # Upgrade installed tools (no args = only out-of-date tools)
43
+ code-aide upgrade [NAMES]
44
+
45
+ # Remove tools
46
+ code-aide remove [NAMES]
47
+
48
+ # Check upstream for latest versions (dry-run)
49
+ code-aide update-versions -n
50
+
51
+ # Update version cache
52
+ code-aide update-versions -y
53
+ ```
54
+
55
+ ## Supported Tools
56
+
57
+ | Tool | Command | Install Type | Default |
58
+ |:-------------------------|:-----------|:----------------|:--------|
59
+ | Cursor CLI | `agent` | Direct download | Yes |
60
+ | Claude CLI (Claude Code) | `claude` | Script | Yes |
61
+ | Gemini CLI | `gemini` | npm | Yes |
62
+ | OpenCode | `opencode` | npm | No |
63
+ | Kilo CLI | `kilo` | npm | No |
64
+ | Amp (Sourcegraph) | `amp` | Script | No |
65
+ | Codex CLI | `codex` | npm | No |
66
+ | Copilot CLI | `copilot` | npm | No |
67
+
68
+ ## How Version Data Works
69
+
70
+ code-aide uses a two-layer version data model:
71
+
72
+ 1. **Bundled tool definitions** (in `data/tools.json`): Install methods, URLs,
73
+ npm packages, version args, and SHA256 checksums. Updated by releasing new
74
+ versions of code-aide.
75
+
76
+ 2. **User's local version cache** (`~/.config/code-aide/versions.json`): Written
77
+ by `code-aide update-versions`. Provides latest versions, dates, and updated
78
+ SHA256 checksums.
79
+
80
+ Run `code-aide update-versions` to get the latest version data without waiting
81
+ for a new code-aide release.
82
+
83
+ ## Tool definition schema (`data/tools.json`)
84
+
85
+ Each entry in `tools.json` describes one managed tool. Required fields are
86
+ `name`, `command`, and `install_type`; the others are optional and only
87
+ consulted when the relevant install method or platform applies.
88
+
89
+ | Field | Required | Notes |
90
+ |:------------------------------|:---------|:---------------------------------------------------------------------------------------------|
91
+ | `name` | Yes | Display name for status output |
92
+ | `command` | Yes | Binary name (looked up in `PATH`) |
93
+ | `install_type` | Yes | One of `npm`, `script`, `direct_download`, `pkg` |
94
+ | `version_args` | No | List of arguments passed to the binary to print its version (default: `["--version"]`) |
95
+ | `version_url` | No | URL queried by `update-versions` to discover the latest upstream version |
96
+ | `latest_version` | Cache | Last known upstream version (filled by `update-versions`) |
97
+ | `latest_date` | Cache | Release date for `latest_version` |
98
+ | `prerequisites` | No | List of required external commands (e.g. `["npm"]`) |
99
+ | `min_node_version` | No | Minimum major Node.js version required |
100
+ | `npm_package` | npm | npm package name (e.g. `@anthropic-ai/claude-code`) |
101
+ | `install_url` | script | URL of the install script that will be downloaded and piped to `bash` |
102
+ | `install_sha256` | script | SHA-256 of the install script body — required for verified installs |
103
+ | `install_script_path_prepend` | script | Extra directories prepended to `PATH` when the install script runs (e.g. `["~/.local/bin"]`) |
104
+ | `download_url_template` | direct | URL template with `{version}`, `{os}`, `{arch}` placeholders |
105
+ | `install_dir` | direct | Directory to extract into; supports `{version}` |
106
+ | `bin_dir` | direct | Directory where symlinks for `command` are created (e.g. `~/.local/bin`) |
107
+ | `symlinks` | direct | Map of `link_name` → relative path inside `install_dir` to symlink into `bin_dir` |
108
+ | `freebsd_port` | FreeBSD | FreeBSD ports/pkg name (used when running on FreeBSD) |
109
+ | `freebsd_pkg_repo` | FreeBSD | Optional non-default pkg repository name (passed via `pkg install -r <repo>`) |
110
+ | `next_steps` | No | Free-form text printed after a successful install |
111
+ | `docs_url` | No | Documentation URL printed after install |
112
+
113
+ ## Features
114
+
115
+ - Zero external dependencies (Python stdlib only)
116
+ - SHA256 verification for script-based installations
117
+ - Automatic prerequisite detection and installation (Node.js, npm)
118
+ - Detects install method (Homebrew, npm, system package, script, direct
119
+ download)
120
+ - PATH configuration validation and warnings
121
+ - Supports Linux and macOS
122
+
123
+ ## Requirements
124
+
125
+ - Python 3.11+
126
+ - No external Python dependencies
127
+
128
+ ## Development
129
+
130
+ 1. Install uv: `curl -LsSf https://astral.sh/uv/install.sh | sh`
131
+ 2. Install dependencies: `uv sync`
132
+ 3. Install pre-commit hooks: `uv tool install pre-commit && pre-commit install`
133
+ 4. Run tests: `uv run pytest tests/ -v`
134
+
135
+ ```bash
136
+ # Run from development checkout
137
+ uv run python -m code_aide status
138
+ uv run python -m code_aide install copilot
139
+
140
+ # Run a specific test
141
+ uv run pytest tests/test_install.py::TestDetectOsArch -v
142
+ ```
143
+
144
+ ## Release
145
+
146
+ `publish.yml` publishes to PyPI when a Git tag matching `v*` is pushed.
147
+
148
+ 1. Update the version string in `src/code_aide/__init__.py` (`__version__`).
149
+ `pyproject.toml` reads it automatically via Hatchling.
150
+ 2. Run checks:
151
+ - `uv run pytest tests/ -v`
152
+ - `uv build`
153
+ 3. Commit the release version bump:
154
+ - `git add src/code_aide/__init__.py`
155
+ - `git commit -m "Bumped version to X.Y.Z"`
156
+ 4. Write useful commit messages before tagging:
157
+ - Start subject lines with an action verb in past tense (`Added`, `Changed`,
158
+ `Fixed`, `Removed`).
159
+ - Keep subjects user-facing so auto-generated release notes are meaningful.
160
+ - Group related changes into focused commits instead of one broad commit.
161
+ - Example: `Fixed timeout handling in status command`
162
+ 5. Tag and push:
163
+ - `git tag vX.Y.Z`
164
+ - `git push origin main`
165
+ - `git push origin vX.Y.Z`
166
+ 6. Confirm GitHub Actions:
167
+ - CI should pass.
168
+ - Publish workflow should upload to PyPI and create GitHub Release notes.
169
+ - Release notes should include generated notes plus a commit summary from the
170
+ previous tag to the current tag.
171
+
172
+ ## License
173
+
174
+ Apache-2.0
@@ -11,7 +11,7 @@ remove, status, and version metadata).
11
11
  | 2 | Read version from stdout+stderr | Med | Low | Some tools write version to stderr; shown as not installed |
12
12
  | 3 | Atomic version cache writes | Med-High | Low | Process crash can corrupt `versions.json` |
13
13
  | 4 | Warn on invalid cache JSON | Low | Low | Silent data loss; user sees empty versions |
14
- | 5 | Use `os.pathsep` not `":"` | High | Trivial | Breaks PATH checks on Windows entirely |
14
+ | 5 | ~~Use `os.pathsep` not `":"`~~ (done) | - | - | Fixed in `prereqs.py` `check_path_directories()` |
15
15
  | 6 | Verify direct-download tarballs | High | Med | No integrity check before extracting; MITM risk |
16
16
  | 7 | Tarball checksum metadata fields | High | Low | Prerequisite for item 6 |
17
17
  | 8 | `--json` output mode | Low | Med | Needed for CI/automation consumers |
@@ -30,21 +30,21 @@ remove, status, and version metadata).
30
30
 
31
31
  - [ ] Handle missing `node` cleanly during prerequisite checks
32
32
  (`FileNotFoundError` path in Node version probing).
33
- - [ ] Read tool version output from both stdout and stderr so status does
34
- not miss installed versions.
33
+ - [ ] Read tool version output from both stdout and stderr so status does not
34
+ miss installed versions.
35
35
  - [ ] Make version cache writes atomic (write temp file + rename) to avoid
36
36
  partial/corrupted `versions.json`.
37
- - [ ] Warn when `versions.json` cache contains invalid JSON instead of
38
- silently returning empty data.
39
- - [ ] Use `os.pathsep` instead of hardcoded `":"` in `prereqs.py`
37
+ - [ ] Warn when `versions.json` cache contains invalid JSON instead of silently
38
+ returning empty data.
39
+ - [x] Use `os.pathsep` instead of hardcoded `":"` in `prereqs.py`
40
40
  `check_path_directories()`.
41
41
 
42
42
  ## Security and Integrity
43
43
 
44
- - [ ] Add integrity verification for direct-download tarballs (not only
45
- install script SHA256).
46
- - [ ] Extend tool metadata to support tarball checksum/signature fields
47
- where applicable.
44
+ - [ ] Add integrity verification for direct-download tarballs (not only install
45
+ script SHA256).
46
+ - [ ] Extend tool metadata to support tarball checksum/signature fields where
47
+ applicable.
48
48
 
49
49
  ## CLI and Automation UX
50
50
 
@@ -52,21 +52,19 @@ remove, status, and version metadata).
52
52
  - [ ] Add a focused `doctor` command for environment checks (PATH,
53
53
  prerequisites, command health).
54
54
  - [ ] Consider `install --force` for reinstall/repair flows.
55
- - [ ] Add cleanup support for stale direct-download versions no longer in
56
- use.
55
+ - [ ] Add cleanup support for stale direct-download versions no longer in use.
57
56
 
58
57
  ## Documentation
59
58
 
60
- - [ ] Document that running `code-aide` with no subcommand defaults to
61
- `status`.
59
+ - [ ] Document that running `code-aide` with no subcommand defaults to `status`.
62
60
  - [ ] Add `install --dryrun` to the README usage examples.
63
61
  - [ ] Document environment variables and config file paths
64
62
  (`~/.config/code-aide/versions.json`).
65
63
 
66
64
  ## Platform and Package Detection
67
65
 
68
- - [ ] Broaden system package metadata detection beyond Gentoo-specific
69
- tooling where practical.
66
+ - [ ] Broaden system package metadata detection beyond Gentoo-specific tooling
67
+ where practical.
70
68
 
71
69
  ## Maintainability and Tests
72
70
 
@@ -43,6 +43,21 @@ path = "src/code_aide/__init__.py"
43
43
 
44
44
  [tool.pytest.ini_options]
45
45
  testpaths = ["tests"]
46
+ filterwarnings = [
47
+ "error",
48
+ "ignore::DeprecationWarning:_pytest.*",
49
+ ]
50
+ markers = [
51
+ "network: tests that make real network calls (deselect with '-m \"not network\"')",
52
+ ]
53
+
54
+ [tool.mypy]
55
+ python_version = "3.11"
56
+ files = ["src/code_aide"]
57
+ warn_unused_ignores = true
58
+ warn_redundant_casts = true
59
+ warn_unused_configs = true
60
+ no_implicit_optional = true
46
61
 
47
62
  [dependency-groups]
48
63
  dev = [
@@ -50,4 +65,5 @@ dev = [
50
65
  "pytest-xdist>=3.0",
51
66
  "black>=25.1.0",
52
67
  "ruff>=0.9.0",
68
+ "mypy>=1.10",
53
69
  ]
@@ -240,18 +240,10 @@ install_amp_binary() {
240
240
  log "Installing version: $version"
241
241
  fi
242
242
 
243
- # Use versioned URLs if available, fall back to root for backwards compatibility
244
243
  local binary_url="$STORAGE_BASE/cli/${version}/amp-${platform}"
245
244
  local checksum_url="$STORAGE_BASE/cli/${version}/${platform}-amp.sha256"
246
245
  local minisign_signature_url="$binary_url.minisig"
247
246
 
248
- # Check if versioned path exists, fall back to root path
249
- if ! curl -fsSL --head "$checksum_url" >/dev/null 2>&1; then
250
- binary_url="$STORAGE_BASE/cli/amp-${platform}"
251
- checksum_url="$STORAGE_BASE/cli/${platform}-amp.sha256"
252
- minisign_signature_url="$binary_url.minisig"
253
- fi
254
-
255
247
  # Add .exe for Windows downloads
256
248
  if [[ "$platform" == *"windows"* ]]; then
257
249
  binary_url="${binary_url}.exe"
@@ -107,6 +107,13 @@ mkdir -p "$DOWNLOAD_DIR"
107
107
  # Always download latest version (which has the most up-to-date installer)
108
108
  version=$(download_file "$DOWNLOAD_BASE_URL/latest")
109
109
 
110
+ # Reject non-version content (e.g. an HTML error page) before it reaches the manifest URL
111
+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
112
+ echo "Failed to get a valid version from downloads.claude.ai (got unexpected content)." >&2
113
+ echo "This can happen if the download service is unreachable or not available in your region - see https://www.anthropic.com/supported-countries" >&2
114
+ exit 1
115
+ fi
116
+
110
117
  # Download manifest and extract checksum
111
118
  manifest_json=$(download_file "$DOWNLOAD_BASE_URL/$version/manifest.json")
112
119