code-aide 1.15.1__tar.gz → 1.15.3__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.
- code_aide-1.15.3/AGENTS.md +41 -0
- code_aide-1.15.3/PKG-INFO +202 -0
- code_aide-1.15.3/README.md +175 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/TODO.md +14 -16
- {code_aide-1.15.1 → code_aide-1.15.3}/pyproject.toml +16 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/script-archive/claude-install.sh +7 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/script-archive/cursor-install.sh +5 -5
- code_aide-1.15.3/specs/2026-05-03-qwen3.6-code-quality-analysis-original.md +196 -0
- code_aide-1.15.3/specs/2026-05-03-qwen3.6-code-quality-analysis.md +296 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/__init__.py +1 -1
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/commands_tools.py +7 -6
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/config.py +15 -6
- code_aide-1.15.3/src/code_aide/console.py +62 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/constants.py +12 -3
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/data/tools.json +1 -1
- code_aide-1.15.3/src/code_aide/detection.py +236 -0
- code_aide-1.15.3/src/code_aide/detection_types.py +26 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/entry.py +22 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/install.py +3 -1
- code_aide-1.15.3/src/code_aide/operation_handlers.py +240 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/operations.py +21 -196
- code_aide-1.15.1/src/code_aide/detection.py → code_aide-1.15.3/src/code_aide/package_info.py +30 -218
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/prereqs.py +1 -1
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/status.py +15 -122
- code_aide-1.15.3/src/code_aide/status_print.py +126 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/versions.py +7 -2
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_commands_actions.py +6 -6
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_commands_tools.py +8 -8
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_console.py +9 -3
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_detection.py +20 -19
- code_aide-1.15.3/tests/test_entry.py +105 -0
- code_aide-1.15.3/tests/test_error_paths.py +332 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_install.py +16 -9
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_operations.py +21 -20
- code_aide-1.15.3/tests/test_prereqs.py +253 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_versions.py +25 -0
- code_aide-1.15.3/uv.lock +381 -0
- code_aide-1.15.1/AGENTS.md +0 -32
- code_aide-1.15.1/PKG-INFO +0 -174
- code_aide-1.15.1/README.md +0 -147
- code_aide-1.15.1/src/code_aide/console.py +0 -58
- code_aide-1.15.1/uv.lock +0 -243
- {code_aide-1.15.1 → code_aide-1.15.3}/.github/workflows/ci.yml +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/.github/workflows/publish.yml +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/.gitignore +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/.gitlab-ci.yml +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/.pre-commit-config.yaml +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/CLAUDE.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/LICENSE +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/script-archive/README.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/script-archive/amp-install.sh +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/auto-migrate-deprecated-installs.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/claude-native-installer-migration.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/missing-coding-llm-cli-tools.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/pre-commit-uv-setup.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/remove-bundled-version-baseline.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/specs/unify-upgrade-eligibility-with-shared-evaluator.md +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/__main__.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/commands_actions.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/install_types.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/src/code_aide/package_managers.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_config.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_constants.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_install_types.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_package_managers.py +0 -0
- {code_aide-1.15.1 → code_aide-1.15.3}/tests/test_status.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# AGENTS.md - AI Coding Agent Instructions
|
|
2
|
+
|
|
3
|
+
- Always use `uv run` to run python code and scripts.
|
|
4
|
+
- Run tests with `uv run pytest`.
|
|
5
|
+
|
|
6
|
+
## Key Design Decisions
|
|
7
|
+
|
|
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
|
+
- Primary supported environments are macOS and Linux (see pyproject
|
|
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.
|
|
26
|
+
- All tests should pass before committing
|
|
27
|
+
- pre-commit runs black and ruff on commit; run `black` to format and then
|
|
28
|
+
`pre-commit run --all-files` to check before committing
|
|
29
|
+
- When changing pyproject.toml dependencies, run `uv lock` and commit uv.lock
|
|
30
|
+
- Write useful commit messages: start subjects with past-tense action verbs
|
|
31
|
+
(`Added`, `Changed`, `Fixed`, `Removed`), keep them user-facing, and keep
|
|
32
|
+
commits focused.
|
|
33
|
+
- Python 3.11+ compatible
|
|
34
|
+
- Keep files under 300 lines where practical
|
|
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
|
|
39
|
+
- For releases, push both the branch and the tag to all remotes (origin, gitlab,
|
|
40
|
+
codeberg): `git push <remote> main && git push <remote> <tag>` for each remote
|
|
41
|
+
in turn.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: code-aide
|
|
3
|
+
Version: 1.15.3
|
|
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 to all remotes (origin/GitHub, gitlab, codeberg):
|
|
190
|
+
- `git tag vX.Y.Z`
|
|
191
|
+
- `git push origin main && git push origin vX.Y.Z`
|
|
192
|
+
- `git push gitlab main && git push gitlab vX.Y.Z`
|
|
193
|
+
- `git push codeberg main && git push codeberg vX.Y.Z`
|
|
194
|
+
6. Confirm GitHub Actions:
|
|
195
|
+
- CI should pass.
|
|
196
|
+
- Publish workflow should upload to PyPI and create GitHub Release notes.
|
|
197
|
+
- Release notes should include generated notes plus a commit summary from the
|
|
198
|
+
previous tag to the current tag.
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
Apache-2.0
|
|
@@ -0,0 +1,175 @@
|
|
|
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 to all remotes (origin/GitHub, gitlab, codeberg):
|
|
163
|
+
- `git tag vX.Y.Z`
|
|
164
|
+
- `git push origin main && git push origin vX.Y.Z`
|
|
165
|
+
- `git push gitlab main && git push gitlab vX.Y.Z`
|
|
166
|
+
- `git push codeberg main && git push codeberg vX.Y.Z`
|
|
167
|
+
6. Confirm GitHub Actions:
|
|
168
|
+
- CI should pass.
|
|
169
|
+
- Publish workflow should upload to PyPI and create GitHub Release notes.
|
|
170
|
+
- Release notes should include generated notes plus a commit summary from the
|
|
171
|
+
previous tag to the current tag.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
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 `":"
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
- [
|
|
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
|
-
|
|
46
|
-
- [ ] Extend tool metadata to support tarball checksum/signature fields
|
|
47
|
-
|
|
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
|
-
|
|
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
|
]
|
|
@@ -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
|
|
|
@@ -75,14 +75,14 @@ print_success "Detected ${OS}/${ARCH}"
|
|
|
75
75
|
# Installation steps
|
|
76
76
|
print_step "Creating installation directory..."
|
|
77
77
|
# Create temporary directory for atomic download inside versions folder
|
|
78
|
-
TEMP_EXTRACT_DIR="$HOME/.local/share/cursor-agent/versions/.tmp-2026.
|
|
78
|
+
TEMP_EXTRACT_DIR="$HOME/.local/share/cursor-agent/versions/.tmp-2026.06.12-19-59-36-f6aba9a-$(date +%s)"
|
|
79
79
|
mkdir -p "${TEMP_EXTRACT_DIR}"
|
|
80
80
|
|
|
81
81
|
print_success "Directory created"
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
print_step "Downloading Cursor Agent package..."
|
|
85
|
-
DOWNLOAD_URL="https://downloads.cursor.com/lab/2026.
|
|
85
|
+
DOWNLOAD_URL="https://downloads.cursor.com/lab/2026.06.12-19-59-36-f6aba9a/${OS}/${ARCH}/agent-cli-package.tar.gz"
|
|
86
86
|
echo -e "${DIM} Download URL: ${DOWNLOAD_URL}${NC}"
|
|
87
87
|
|
|
88
88
|
# Cleanup function
|
|
@@ -107,7 +107,7 @@ fi
|
|
|
107
107
|
|
|
108
108
|
print_step "Finalizing installation..."
|
|
109
109
|
# Atomically move from temp to final destination
|
|
110
|
-
FINAL_DIR="$HOME/.local/share/cursor-agent/versions/2026.
|
|
110
|
+
FINAL_DIR="$HOME/.local/share/cursor-agent/versions/2026.06.12-19-59-36-f6aba9a"
|
|
111
111
|
command rm -rf "${FINAL_DIR}"
|
|
112
112
|
if mv "${TEMP_EXTRACT_DIR}" "${FINAL_DIR}"; then
|
|
113
113
|
print_success "Package installed successfully"
|
|
@@ -127,8 +127,8 @@ print_step "Creating symlinks to agent executable..."
|
|
|
127
127
|
# Remove any existing symlink or file
|
|
128
128
|
command rm -f ~/.local/bin/agent ~/.local/bin/cursor-agent
|
|
129
129
|
# Create symlinks to the Cursor Agent executable (primary: agent, legacy: cursor-agent)
|
|
130
|
-
ln -s ~/.local/share/cursor-agent/versions/2026.
|
|
131
|
-
ln -s ~/.local/share/cursor-agent/versions/2026.
|
|
130
|
+
ln -s ~/.local/share/cursor-agent/versions/2026.06.12-19-59-36-f6aba9a/cursor-agent ~/.local/bin/agent
|
|
131
|
+
ln -s ~/.local/share/cursor-agent/versions/2026.06.12-19-59-36-f6aba9a/cursor-agent ~/.local/bin/cursor-agent
|
|
132
132
|
print_success "Symlink created"
|
|
133
133
|
|
|
134
134
|
# Success message
|