cdx-manager 0.18.0 → 0.18.1
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.
- package/README.md +1 -1
- package/changelogs/CHANGELOGS_0_18_1.md +50 -0
- package/checksums/release-archives.json +10 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/tray_install.py +16 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CDX Manager
|
|
2
2
|
|
|
3
|
-
[](LICENSE) ](LICENSE)  
|
|
4
4
|
|
|
5
5
|
**Stop guessing which AI account still has quota.** `cdx` tracks the rate-limit window of every Codex and Claude account you own, tells you which one is usable right now, and launches it with isolated auth — in one command.
|
|
6
6
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# CDX Manager 0.18.1
|
|
2
|
+
|
|
3
|
+
## Fixes
|
|
4
|
+
|
|
5
|
+
### `cdx tray install` works against a published release
|
|
6
|
+
|
|
7
|
+
0.18.0 shipped a tray installer that refused every asset the release published.
|
|
8
|
+
Three separate causes, each of which only appeared when installing from a real
|
|
9
|
+
release rather than from a locally built archive.
|
|
10
|
+
|
|
11
|
+
**The archive shape was rejected.** Release assets are written with
|
|
12
|
+
`tar -C dir .`, so they carry a member for the directory itself. The guard that
|
|
13
|
+
refuses an archive escaping its install directory treated that member as an
|
|
14
|
+
escape, when it resolves to the destination and nothing else. The destination is
|
|
15
|
+
now accepted; an archive that genuinely writes outside its directory is still
|
|
16
|
+
refused, and a link member still is.
|
|
17
|
+
|
|
18
|
+
**Windows asked for an asset nobody builds.** CDX looked for
|
|
19
|
+
`x86_64-pc-windows-gnu` while releases are built with the MSVC toolchain, so no
|
|
20
|
+
published checksum ever matched the name it asked for. Every Windows install
|
|
21
|
+
refused for want of a checksum that was published under a different target.
|
|
22
|
+
|
|
23
|
+
**ARM Linux was offered and never built.** `aarch64-unknown-linux-musl` was a
|
|
24
|
+
target CDX would install and the release did not produce. It is now built and
|
|
25
|
+
published alongside the others.
|
|
26
|
+
|
|
27
|
+
A test now asserts that every target CDX offers is one the release actually
|
|
28
|
+
builds, so this class of mismatch fails in CI rather than on a user's machine.
|
|
29
|
+
|
|
30
|
+
### Windows toasts carry the CDX icon
|
|
31
|
+
|
|
32
|
+
The Start Menu shortcut CDX installs now points at an icon shipped with the
|
|
33
|
+
companion, so a notification shows the CDX logo rather than a generic one.
|
|
34
|
+
Uninstall removes the shortcut along with the companion.
|
|
35
|
+
|
|
36
|
+
## Release safety
|
|
37
|
+
|
|
38
|
+
Publishing to npm and PyPI now waits for the tray companion assets to build
|
|
39
|
+
successfully. All four workflows fire on the same release event, so previously
|
|
40
|
+
they ran beside each other: a failed asset build would have left both registries
|
|
41
|
+
carrying a version whose release had no companion to install.
|
|
42
|
+
|
|
43
|
+
## Validation
|
|
44
|
+
|
|
45
|
+
- `npm run lint`
|
|
46
|
+
- `npm test` — 771 Python tests
|
|
47
|
+
- `cargo test` — 45 Rust tests; `cargo clippy` clean with zero warnings on three
|
|
48
|
+
targets
|
|
49
|
+
- `cdx tray install`, `doctor`, `launch` and `uninstall` exercised against the
|
|
50
|
+
published v0.18.0 assets on macOS arm64, Windows, and Linux under WSL
|
|
@@ -192,6 +192,16 @@
|
|
|
192
192
|
"v0.17.1": {
|
|
193
193
|
"github_tarball_sha256": "f1cc36d55f17d8e5c8ad0b0ebc419e812b8788742c3e45ce1137303924114dd7",
|
|
194
194
|
"github_zip_sha256": "29acb306ad76535d0db701504a53b9887b8a6b0b95d968634139f85952a34ec3"
|
|
195
|
+
},
|
|
196
|
+
"v0.18.0": {
|
|
197
|
+
"github_tarball_sha256": "ae666d8ec38a74859e1edc5023101474a2fb647ecb3ba285fd746c7b84699854",
|
|
198
|
+
"github_zip_sha256": "72ecdd02b449c2256a74f77afec7eda8cd9b53b52bb62858e45d3d6000a1bd24",
|
|
199
|
+
"tray_assets": {
|
|
200
|
+
"aarch64-apple-darwin": "45aa98624bda29dea26637aeb22a86b22fe018a95fb176bfffd3504c772c9988",
|
|
201
|
+
"x86_64-apple-darwin": "d310852919cd4e2ddce2108044d0039e088b5bdc3dfa029be4d81ee0df1c420b",
|
|
202
|
+
"x86_64-pc-windows-msvc": "86e29cbdbcf070aec7fd34e5596343a43f2b5092e634ca094aba96abf1d49884",
|
|
203
|
+
"x86_64-unknown-linux-musl": "36ef879c0e75f3c367ed48f1f5a67e25698ec5a04c70958b48ae0885f87487d8"
|
|
204
|
+
}
|
|
195
205
|
}
|
|
196
206
|
}
|
|
197
207
|
}
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
package/src/tray_install.py
CHANGED
|
@@ -32,7 +32,11 @@ CHECKSUM_LEDGER = os.path.join(
|
|
|
32
32
|
TARGETS = {
|
|
33
33
|
("Darwin", "arm64"): "aarch64-apple-darwin",
|
|
34
34
|
("Darwin", "x86_64"): "x86_64-apple-darwin",
|
|
35
|
-
|
|
35
|
+
# msvc, not gnu: this has to name the asset the release actually publishes,
|
|
36
|
+
# and the release workflow builds on windows-latest with the default MSVC
|
|
37
|
+
# toolchain. A mismatch here is not a degraded install, it is a refusal —
|
|
38
|
+
# there is no checksum published under a target nobody built.
|
|
39
|
+
("Windows", "AMD64"): "x86_64-pc-windows-msvc",
|
|
36
40
|
("Linux", "x86_64"): "x86_64-unknown-linux-musl",
|
|
37
41
|
("Linux", "aarch64"): "aarch64-unknown-linux-musl",
|
|
38
42
|
}
|
|
@@ -214,9 +218,14 @@ def _extract(archive, destination):
|
|
|
214
218
|
"""
|
|
215
219
|
names = []
|
|
216
220
|
with tarfile.open(archive, "r:gz") as tar:
|
|
221
|
+
root = os.path.realpath(destination)
|
|
217
222
|
for member in tar.getmembers():
|
|
218
223
|
resolved = os.path.realpath(os.path.join(destination, member.name))
|
|
219
|
-
|
|
224
|
+
# The destination itself is not an escape. An archive written with
|
|
225
|
+
# `tar -C dir .` carries a `.` member for the directory, which is
|
|
226
|
+
# what the release workflow produces — and rejecting it refused
|
|
227
|
+
# every published asset while the archive was perfectly safe.
|
|
228
|
+
if resolved != root and not resolved.startswith(root + os.sep):
|
|
220
229
|
raise TrayInstallError(
|
|
221
230
|
f"{os.path.basename(archive)} tries to write outside its install directory "
|
|
222
231
|
f"({member.name}). Nothing was installed."
|
|
@@ -254,7 +263,11 @@ def _executable_in(destination, names):
|
|
|
254
263
|
bundles = [n for n in names if candidate(n).endswith(".app")]
|
|
255
264
|
binaries = [n for n in names if candidate(n) in ("cdx-tray", "cdx-tray.exe")]
|
|
256
265
|
for name in bundles + binaries:
|
|
257
|
-
|
|
266
|
+
# Normalised because an archive written with `tar -C dir .` names its
|
|
267
|
+
# members `./CDX.app`, and this path is recorded, launched, and removed
|
|
268
|
+
# later — a `/./` in the middle works but reads like a defect to anyone
|
|
269
|
+
# looking at the install record or a doctor report.
|
|
270
|
+
path = os.path.normpath(os.path.join(destination, name.rstrip("/")))
|
|
258
271
|
if os.path.isdir(path):
|
|
259
272
|
return path
|
|
260
273
|
if os.path.isfile(path):
|