cdx-manager 0.25.5 → 0.25.7
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/VERSION +1 -1
- package/changelogs/CHANGELOGS_0_25_6.md +15 -0
- package/changelogs/CHANGELOGS_0_25_7.md +15 -0
- package/changelogs/CHANGELOGS_UNRELEASED.md +7 -1
- package/checksums/release-archives.json +22 -0
- package/docs/cli.md +29 -8
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/commands/maintenance.py +2 -1
- package/src/update_all.py +39 -9
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<br clear="left"/>
|
|
6
6
|
|
|
7
|
-
[](LICENSE) ](LICENSE)  
|
|
8
8
|
|
|
9
9
|
**The right AI coding account, when you need it.** CDX Manager keeps your Codex and Claude accounts in separate profiles, shows which ones have quota, and helps you pick the next usable session from your terminal.
|
|
10
10
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.25.
|
|
1
|
+
0.25.7
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CDX Manager 0.25.6
|
|
2
|
+
|
|
3
|
+
Release date: 2026-11-02
|
|
4
|
+
|
|
5
|
+
This patch release fixes provider update detection and verifies installed versions after updates.
|
|
6
|
+
|
|
7
|
+
## Fixes
|
|
8
|
+
|
|
9
|
+
- Detect advertised provider updaters and version output on both stdout and stderr. After an update, verify the installed version and report failure if it is missing, unchanged, downgraded, or still below the published version. Successful text output shows the version transition, and JSON results include before, after, and latest versions. (#87)
|
|
10
|
+
- Fall back to the latest stable GitHub release when Ollama's vendor API returns an empty, invalid, or failed response. Keep Linux Ollama updates manual, with an explicit maintenance reason. (#87)
|
|
11
|
+
|
|
12
|
+
## Maintenance
|
|
13
|
+
|
|
14
|
+
- Record tray companion checksums for v0.25.5. (`b64a372f9ab4abb61f1440943fca19703ad555eb`)
|
|
15
|
+
- Record release archive checksums for v0.25.5. (`1218145eae4201e40b8140e7a94cbcec18454e17`)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CDX Manager 0.25.7
|
|
2
|
+
|
|
3
|
+
Release date: 2026-11-02
|
|
4
|
+
|
|
5
|
+
This patch release corrects Antigravity CLI update detection and verification.
|
|
6
|
+
|
|
7
|
+
## Fixes
|
|
8
|
+
|
|
9
|
+
- Stop comparing Antigravity CLI (`agy`) versions against the editor release feed. Report the latest CLI version as unknown and let the native `agy update` command check and apply updates after confirmation, including with `--yes`. Inventory collection remains read-only. (#89)
|
|
10
|
+
- Accept a successful updater's explicit `You are already on the latest version.` message on stdout or stderr when the installed version is unchanged. Otherwise require a verified version increase reaching the published version when known, and preserve updater failures. (#89)
|
|
11
|
+
|
|
12
|
+
## Maintenance
|
|
13
|
+
|
|
14
|
+
- Record tray companion checksums for v0.25.6. (`53500823f04edb69be9563d327645148439644a6`)
|
|
15
|
+
- Record release archive checksums for v0.25.6. (`974dfb0cac31963883456bda4beddb19b8940152`)
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Truthful workstation updates
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- Stop querying the editor release feed for the Antigravity CLI: its versions do not match `agy`. Keep `latest_version: null` and `status: unknown`, while still running the native `agy update` with `--yes` or confirmation. No read-only latest-version check is documented by `agy update --help`.
|
|
6
|
+
- Accept a successful native updater's `You are already on the latest version.` message when the installed version is unchanged, or verify a version increase against the published version when known. Preserve updater failures and unknown inventory status. Cover the real Antigravity output line, version increases, failures, and JSON/text uncertainty.
|
|
7
|
+
|
|
8
|
+
- Detect advertised native updater subcommands in both stdout and stderr; use Antigravity's known `agy update` command directly. Verify the installed CLI version after updating, fail unverified updates unless an unchanged version is explicitly confirmed current by the updater, and expose before/after versions without hiding major upgrades.
|
|
9
|
+
- Fall back from empty or failed Ollama vendor responses (including Linux HTTP 204) to the latest stable `ollama/ollama` GitHub release. Keep Linux updates manual with `update_available`, a null command, and a service-safety reason; never replace a potentially active binary or restart models automatically.
|
|
10
|
+
|
|
11
|
+
- Verify latest versions from npm, RTK GitHub releases, and Ollama vendor update endpoints with short read-only probes. Report `unknown` on unavailable evidence; reserve `up_to_date` for identical known versions, including Ponytail revisions.
|
|
6
12
|
- Preserve the existing JSON fields and `update_available` status, show uncertainty and manual-update reasons in text, and apply only supported native commands or verified Homebrew package upgrades. Cover matching/outdated versions, source failures, missing tools, and command execution with faked sources.
|
|
7
13
|
|
|
8
14
|
## Dependency security
|
|
@@ -738,6 +738,28 @@
|
|
|
738
738
|
"x86_64-pc-windows-msvc": "8e2c1925f025a7227ef909f27e8b4696c03bb5a86e0c61c989da6a942b5638a6",
|
|
739
739
|
"x86_64-unknown-linux-musl": "9ae1164abc3ff4b30d25c44696569855138f8ac0e3b6e1c3451c716d20f221fa"
|
|
740
740
|
}
|
|
741
|
+
},
|
|
742
|
+
"v0.25.5": {
|
|
743
|
+
"github_tarball_sha256": "4a2ece21e32f59a84d8bc7b2a565817c6c90bb314f179319bc19cf85a0c71a60",
|
|
744
|
+
"github_zip_sha256": "959de4dca501fd53c937f4045936b12acbea58d255a4e3cae510ec82a230bef8",
|
|
745
|
+
"tray_assets": {
|
|
746
|
+
"aarch64-apple-darwin": "727c4ded1ee4d9d8ed9853badcb10efd1cc76bd6dcd6012b6739920d42e6273c",
|
|
747
|
+
"aarch64-unknown-linux-musl": "9270224db6be83d4a4787f9b523a6fa059267f56ed1cf12f022f65bf68c0474f",
|
|
748
|
+
"x86_64-apple-darwin": "10c555671cdeb3ce4c0372f6f8a48e6cfeac9132e980c466fe5a8978dc1a2862",
|
|
749
|
+
"x86_64-pc-windows-msvc": "85945b30580cb82c64ece94652ae0633a6156dfd85e02108c0d4b7676cab9911",
|
|
750
|
+
"x86_64-unknown-linux-musl": "7c5a23938b84c5952be71b5956ed3167c218d05ce661940b0c86f2dde2d8221f"
|
|
751
|
+
}
|
|
752
|
+
},
|
|
753
|
+
"v0.25.6": {
|
|
754
|
+
"github_tarball_sha256": "27663ea4f9c70aafb1d2180d36563ab10d91b9cb336cb3285ed4fd610e698bed",
|
|
755
|
+
"github_zip_sha256": "ba645956971ddd9446389717ad48a74dfb426ff7290c5ebc100ca9e3c2a91d3f",
|
|
756
|
+
"tray_assets": {
|
|
757
|
+
"aarch64-apple-darwin": "41b8d1a0b098407a49fc66ef2b49fbf8283f46f6393f34fae05d0ee3b84fcd1b",
|
|
758
|
+
"aarch64-unknown-linux-musl": "ba88584f8ba6399572961feb4d7bcc056096d3aa398d863bc0e248e57086434e",
|
|
759
|
+
"x86_64-apple-darwin": "ddd032fe6306585397c4c4a461de28cafea5519eb08502224fb5ad87a249b05a",
|
|
760
|
+
"x86_64-pc-windows-msvc": "5c3c4be1dcf6801ed0ed73bef8840deb379e2724d9728f983498d0fe5a99c542",
|
|
761
|
+
"x86_64-unknown-linux-musl": "ba91c1378b78e529da3af35c7e649ed2063ba27963ef91949f1aabe9e3fe2a0f"
|
|
762
|
+
}
|
|
741
763
|
}
|
|
742
764
|
}
|
|
743
765
|
}
|
package/docs/cli.md
CHANGED
|
@@ -560,26 +560,47 @@ Versions and commands are explicitly `null` when unavailable.
|
|
|
560
560
|
- `not_installed`: the executable is absent; no installation is guessed.
|
|
561
561
|
|
|
562
562
|
Checks use the npm registry for Codex and `@anthropic-ai/claude-code`, GitHub's
|
|
563
|
-
`rtk-ai/rtk` latest stable release,
|
|
564
|
-
`/releases` feed for `agy`, and Ollama's own `/api/update` endpoint with the local
|
|
563
|
+
`rtk-ai/rtk` latest stable release, and Ollama's own `/api/update` endpoint with the local
|
|
565
564
|
OS/architecture and baseline version `0.0.0`. Ollama's local `/api/version` reports
|
|
566
565
|
an installed server, not the latest published release, and is not used.
|
|
567
|
-
Antigravity
|
|
566
|
+
Antigravity's editor `/releases` feed does not describe the `agy` CLI and is not
|
|
567
|
+
queried. `agy update --help` documents no read-only version check, so its latest
|
|
568
|
+
CLI version stays unknown (`latest_version: null`, `status: unknown`). CDX still
|
|
569
|
+
includes `agy update`, the CLI's own updater, in the plan. It runs only with
|
|
570
|
+
`--yes` or confirmation. Inventory collection never runs that updater.
|
|
568
571
|
HTTP and read-only CLI probes have a five-second timeout; source failures leave
|
|
569
572
|
`latest_version: null` and `status: unknown`. Ponytail also reports `unknown`
|
|
570
|
-
when its remote revision is unavailable. An empty
|
|
571
|
-
HTTP 204
|
|
572
|
-
|
|
573
|
+
when its remote revision is unavailable. An empty, failed, or invalid Ollama
|
|
574
|
+
response (including Linux HTTP 204) falls back to the latest stable GitHub
|
|
575
|
+
release for `ollama/ollama`. If that source also fails, status is `unknown`;
|
|
576
|
+
a different platform's vendor response is never substituted.
|
|
573
577
|
|
|
574
578
|
For an outdated tool, CDX uses a native update command advertised by its
|
|
575
|
-
`--help` (including Claude and
|
|
579
|
+
`--help` on either stdout or stderr (including Claude and RTK
|
|
580
|
+
when available), Codex's updater,
|
|
576
581
|
or Homebrew only when the resolved executable belongs to a Caskroom/Cellar
|
|
577
582
|
package. An outdated tool without such a path retains `update_available`,
|
|
578
583
|
`update_command: null`, and a human-readable `reason`; it requires the vendor's
|
|
579
|
-
manual update mechanism.
|
|
584
|
+
manual update mechanism. On Linux, Ollama always retains `update_available`
|
|
585
|
+
with `update_command: null` and an explicit maintenance reason: its installer
|
|
586
|
+
writes system paths and may restart a service. A binary in `~/.local/bin` can
|
|
587
|
+
also serve running models, so CDX neither replaces it nor restarts services.
|
|
588
|
+
Arrange a manual maintenance window. Source uncertainty never schedules a guessed install.
|
|
580
589
|
The text table shows `UNKNOWN` and the reason, and an empty action list makes
|
|
581
590
|
no claim that all tools are current. JSON consumers, including external
|
|
582
591
|
remote-ops auto-update scripts, should inspect statuses separately from successful
|
|
583
592
|
command execution: exit code zero means no attempted action failed, not that
|
|
584
593
|
every installed tool was verified current. With `--yes`, the returned plan is the
|
|
585
594
|
pre-update inventory; `results` records attempted actions and their exit codes.
|
|
595
|
+
|
|
596
|
+
After each successful tool update command, CDX probes the CLI version again.
|
|
597
|
+
A raised version succeeds when it reaches the published release, if known.
|
|
598
|
+
An unchanged version also succeeds when the updater explicitly reports
|
|
599
|
+
`You are already on the latest version.` on stdout or stderr and exits zero;
|
|
600
|
+
this does not change an `unknown` inventory status to `up_to_date`.
|
|
601
|
+
Otherwise an unchanged, unreadable, downgraded, or still older-than-published
|
|
602
|
+
version makes the action fail, even if the updater exited zero. Successful text output
|
|
603
|
+
shows the before/after versions, including major upgrades. JSON keeps the
|
|
604
|
+
pre-update plan and existing result fields; tool verification adds
|
|
605
|
+
`version_before`, `version_after`, and `latest_version` to successful-command
|
|
606
|
+
results, plus `reason` and a nonzero `returncode` if verification fails.
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -52,7 +52,8 @@ def _format_update_all_result(result, use_color=False):
|
|
|
52
52
|
if result.get("skipped"):
|
|
53
53
|
return _warn(f"skipped: {result['name']} (blocked by {result['blocked_by']})", use_color)
|
|
54
54
|
if result.get("returncode") == 0:
|
|
55
|
-
|
|
55
|
+
versions = f" ({result['version_before']} -> {result['version_after']})" if "version_after" in result else ""
|
|
56
|
+
return _success(f"done: {result['name']}{versions}", use_color)
|
|
56
57
|
detail = str(result.get("stderr") or result.get("stdout") or "No error output.").strip().replace("\n", " ")
|
|
57
58
|
detail = detail[-500:]
|
|
58
59
|
command = shlex.join(result.get("command") or [])
|
package/src/update_all.py
CHANGED
|
@@ -19,7 +19,6 @@ _TOOLS = (
|
|
|
19
19
|
("rtk", "rtk"),
|
|
20
20
|
)
|
|
21
21
|
_SOURCE_TIMEOUT = 5
|
|
22
|
-
_ANTIGRAVITY_RELEASES = "https://antigravity-auto-updater-974169037036.us-central1.run.app/releases"
|
|
23
22
|
_PONYTAIL_URL = "https://github.com/DietrichGebert/ponytail.git"
|
|
24
23
|
|
|
25
24
|
|
|
@@ -56,7 +55,7 @@ def _version(command, env, runner):
|
|
|
56
55
|
result = _run([command, "--version"], env, runner, timeout=_SOURCE_TIMEOUT)
|
|
57
56
|
if result["returncode"]:
|
|
58
57
|
return None
|
|
59
|
-
text = (result["stdout"] or result["stderr"] or "").strip()
|
|
58
|
+
text = "\n".join((result["stdout"] or "", result["stderr"] or "")).strip()
|
|
60
59
|
# Ollama can print the server version before the CLI version.
|
|
61
60
|
client = re.search(r"client version is (\S+)", text)
|
|
62
61
|
match = client or re.search(r"\b(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\b", text)
|
|
@@ -79,15 +78,22 @@ def _latest_version(name):
|
|
|
79
78
|
if release.get("draft") or release.get("prerelease"):
|
|
80
79
|
return None
|
|
81
80
|
return _parse_version(release["tag_name"])
|
|
82
|
-
if name == PROVIDER_ANTIGRAVITY:
|
|
83
|
-
# agy belongs to the original editor, whose feed differs from Hub and IDE 2.
|
|
84
|
-
return _parse_version(_fetch_json(_ANTIGRAVITY_RELEASES)[0]["version"])
|
|
85
81
|
if name == PROVIDER_OLLAMA:
|
|
86
82
|
arch = {"x86_64": "amd64", "aarch64": "arm64"}.get(platform.machine().lower(), platform.machine().lower())
|
|
87
83
|
query = urlencode({"os": platform.system().lower(), "arch": arch, "version": "0.0.0"})
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
try:
|
|
85
|
+
release = _fetch_json(f"https://ollama.com/api/update?{query}")
|
|
86
|
+
# The vendor updater extracts the release tag from the artifact URL.
|
|
87
|
+
version = _parse_version(os.path.basename(os.path.dirname(urlparse(release["url"]).path)))
|
|
88
|
+
if version:
|
|
89
|
+
return version
|
|
90
|
+
except Exception:
|
|
91
|
+
# Linux can return HTTP 204 with no JSON body.
|
|
92
|
+
pass
|
|
93
|
+
release = _fetch_json("https://api.github.com/repos/ollama/ollama/releases/latest")
|
|
94
|
+
if release.get("draft") or release.get("prerelease"):
|
|
95
|
+
return None
|
|
96
|
+
return _parse_version(release["tag_name"])
|
|
91
97
|
except Exception:
|
|
92
98
|
# A failed or changed source is uncertainty, never evidence of currency.
|
|
93
99
|
return None
|
|
@@ -101,6 +107,10 @@ def _newer(latest, current):
|
|
|
101
107
|
|
|
102
108
|
|
|
103
109
|
def _native_update_command(name, command, path, env, runner):
|
|
110
|
+
if name == PROVIDER_ANTIGRAVITY:
|
|
111
|
+
return [command, "update"]
|
|
112
|
+
if name == PROVIDER_OLLAMA and platform.system().lower() == "linux":
|
|
113
|
+
return None
|
|
104
114
|
real_path = os.path.realpath(path)
|
|
105
115
|
cask = re.search(r"/Caskroom/([^/]+)/", real_path)
|
|
106
116
|
formula = re.search(r"/Cellar/([^/]+)/", real_path)
|
|
@@ -111,7 +121,7 @@ def _native_update_command(name, command, path, env, runner):
|
|
|
111
121
|
return [command, "update"]
|
|
112
122
|
help_result = _run([command, "--help"], env, runner, timeout=_SOURCE_TIMEOUT)
|
|
113
123
|
if help_result["returncode"] == 0:
|
|
114
|
-
help_text = help_result["stdout"]
|
|
124
|
+
help_text = "\n".join((help_result["stdout"] or "", help_result["stderr"] or ""))
|
|
115
125
|
for subcommand in ("self-update", "update", "--update"):
|
|
116
126
|
if re.search(r"(?m)^\s*" + re.escape(subcommand) + r"(?:\s|$)", help_text):
|
|
117
127
|
return [command, subcommand]
|
|
@@ -153,9 +163,17 @@ def collect_update_all_plan(service, env=None, runner=None):
|
|
|
153
163
|
steps.append({"name": name, "command": item["update_command"], "env": {}})
|
|
154
164
|
else:
|
|
155
165
|
item["reason"] = "No supported CLI updater or verified Homebrew installation; use the vendor's updater manually."
|
|
166
|
+
if name == PROVIDER_OLLAMA and platform.system().lower() == "linux":
|
|
167
|
+
item["reason"] = ("No supported safe automatic Linux update: Ollama's installer writes system paths and may restart a service. "
|
|
168
|
+
"Even a user-local binary may serve running models; arrange a manual maintenance window.")
|
|
156
169
|
else:
|
|
157
170
|
item["status"] = "unknown"
|
|
158
171
|
item["reason"] = "Latest version unavailable from the official source." if not latest else "Installed version unavailable or does not match the published release."
|
|
172
|
+
if name == PROVIDER_ANTIGRAVITY:
|
|
173
|
+
# The editor release feed does not describe agy's CLI versions.
|
|
174
|
+
item["reason"] = "Latest CLI version unknown; agy update checks and applies its own updates."
|
|
175
|
+
item["update_command"] = _native_update_command(name, command, path, env, runner)
|
|
176
|
+
steps.append({"name": name, "command": item["update_command"], "env": {}})
|
|
159
177
|
items.append(item)
|
|
160
178
|
|
|
161
179
|
rtk_available = any(item["name"] == "rtk" and item["installed"] for item in items)
|
|
@@ -214,6 +232,18 @@ def apply_update_all_plan(plan, service, env=None, runner=None, progress=None):
|
|
|
214
232
|
continue
|
|
215
233
|
result = _run(step["command"], {**env, **step.get("env", {})}, runner, timeout=120)
|
|
216
234
|
result = {"name": step["name"], "command": step["command"], **result}
|
|
235
|
+
item = next((item for item in plan.get("items", []) if item["name"] == step["name"]), None)
|
|
236
|
+
if result["returncode"] == 0 and item:
|
|
237
|
+
after = _version(item["command"], env, runner)
|
|
238
|
+
result.update(version_before=item["version"], version_after=after, latest_version=item["latest_version"])
|
|
239
|
+
output = "\n".join((result["stdout"], result["stderr"]))
|
|
240
|
+
reports_current = bool(re.search(r"(?im)^\s*You are already on the latest version\.\s*$", output))
|
|
241
|
+
advanced = (_newer(after, item["version"]) and
|
|
242
|
+
(not item["latest_version"] or after == item["latest_version"] or _newer(after, item["latest_version"])))
|
|
243
|
+
if not (advanced or (after and after == item["version"] and reports_current)):
|
|
244
|
+
result["returncode"] = 1
|
|
245
|
+
result["reason"] = "Update verification failed: installed version did not advance to the expected release and updater did not confirm it is current."
|
|
246
|
+
result["stderr"] = (result["stderr"] + "\n" + result["reason"]).strip()
|
|
217
247
|
results.append(result)
|
|
218
248
|
if result["returncode"] == 0 and step.get("id"):
|
|
219
249
|
completed.add(step["id"])
|