cdx-manager 0.9.16 → 0.11.0
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 +80 -10
- package/bin/cdx +2 -11
- package/changelogs/CHANGELOGS_0_10_0.md +43 -0
- package/changelogs/CHANGELOGS_0_11_0.md +51 -0
- package/checksums/release-archives.json +8 -0
- package/install.ps1 +12 -19
- package/install.sh +6 -29
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/claude_refresh.py +17 -33
- package/src/cli.py +163 -28
- package/src/cli_args.py +15 -12
- package/src/cli_commands.py +531 -9
- package/src/cli_helpers.py +33 -38
- package/src/cli_view.py +5 -27
- package/src/codex_usage.py +95 -24
- package/src/notify.py +6 -10
- package/src/provider_runtime.py +58 -14
- package/src/session_service.py +141 -57
- package/src/session_store.py +2 -2
- package/src/status_source.py +47 -25
- package/src/status_view.py +14 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CDX Manager
|
|
2
2
|
|
|
3
|
-
[](LICENSE) ](LICENSE)  
|
|
4
4
|
|
|
5
5
|
**Run multiple Codex, Claude, Antigravity, and Ollama sessions from one terminal. Switch between accounts instantly.**
|
|
6
6
|
|
|
@@ -41,10 +41,12 @@ One command to launch any session. Zero auth juggling.
|
|
|
41
41
|
- **Session control.** Disable a session without deleting it when an account is temporarily out of credits; disabled sessions remain visible and sort last.
|
|
42
42
|
- **Persistent launch settings.** Pin per-session power, permission, and fast-mode preferences once; `cdx` reapplies them on every launch until you unset them.
|
|
43
43
|
- **Launch history.** Inspect recent launches with provider, result, duration, working directory, launch settings, and transcript path.
|
|
44
|
+
- **Disk usage and cleanup.** `cdx disk` reports `CDX_HOME` usage, `cdx disk profiles --candidates` identifies reclaimable profile caches/logs with evidence, and `cdx clean profiles ...` applies explicit cleanup actions.
|
|
44
45
|
- **Update prompts.** Periodic update checks surface `cdx update` directly in the `cdx`, `cdx status`, and launch output when a newer release is available. When `logics-manager` is installed, `cdx` can also suggest `logics-manager self-update`.
|
|
45
46
|
- **Logics viewer shortcut.** `cdx view` opens the Logics browser/focus viewer through `logics-manager view` when the companion CLI is installed. All viewer flags are forwarded: `--lan`, `--lan-rw`, `--focus <ref>`, `--read`, `--port`, `--host`, `--refresh-interval`, `--tls`, `--tls-cert`, `--tls-key`, `--open`, `--no-open`. `cdx view --json` reports availability and update diagnostics without opening the viewer.
|
|
46
47
|
- **Shared handoff context.** Keep a per-workspace Markdown context, or build one from a source session transcript, and install it into another assistant session before switching providers or accounts.
|
|
47
48
|
- **Passive status resolution.** Codex status is read from the local Codex app-server rate-limit API when available, with legacy transcript/history parsing kept as a fallback.
|
|
49
|
+
- **Banked reset visibility.** Eligible Codex accounts show the number of manually redeemable bonus resets in `cdx status` and expose reset details in JSON output.
|
|
48
50
|
- **Session transcript capture.** Every launch is recorded to a local log file via `script`, giving you a full terminal transcript for each session.
|
|
49
51
|
- **Clean removal.** `cdx rmv` wipes a session and its entire auth directory. No orphaned files, no stale credentials.
|
|
50
52
|
|
|
@@ -77,8 +79,6 @@ One command to launch any session. Zero auth juggling.
|
|
|
77
79
|
- Auth probe: synchronous subprocess call to `codex login status` or `claude auth status` before any interactive launch.
|
|
78
80
|
- Signal forwarding: `SIGINT`, `SIGTERM`, and `SIGHUP` are forwarded to the child process and produce clean exit codes.
|
|
79
81
|
- Test stack: `pytest`, `pytest-cov`, and `ruff` via the documented `dev` dependency extra.
|
|
80
|
-
- Python floor decision: `cdx-manager` keeps Python 3.9 support for the 0.9.x line to avoid dropping existing users before a planned compatibility break; classifiers remain aligned with `requires-python = ">=3.9"`.
|
|
81
|
-
|
|
82
82
|
---
|
|
83
83
|
|
|
84
84
|
## Getting Started
|
|
@@ -192,18 +192,18 @@ npm install -g .
|
|
|
192
192
|
|
|
193
193
|
Security note:
|
|
194
194
|
|
|
195
|
-
- The standalone installers
|
|
195
|
+
- The standalone installers resolve official release checksums from the tagged GitHub Release asset `release-archives.json`.
|
|
196
196
|
- You can still override verification explicitly through `CDX_SHA256`.
|
|
197
|
-
- If no checksum is available, standalone installers fail closed unless `CDX_ALLOW_UNVERIFIED=1` is set.
|
|
197
|
+
- If no checksum is available, standalone installers fail closed unless `CDX_ALLOW_UNVERIFIED=1` is set; that override prints a prominent warning before continuing.
|
|
198
198
|
- Prefer `npm`, `pipx`, or `uv` when you want registry-backed install flows.
|
|
199
|
-
- If you use the standalone script, download it first, inspect it, and prefer a release with
|
|
199
|
+
- If you use the standalone script, download it first, inspect it, and prefer a release with the official checksum asset attached.
|
|
200
200
|
|
|
201
201
|
Release maintainer note:
|
|
202
202
|
|
|
203
203
|
- Before publishing npm or PyPI packages, run `npm run release:validate`.
|
|
204
204
|
- The release tag must match `package.json`, `pyproject.toml`, `src/cli.py`, and `VERSION`.
|
|
205
205
|
- `checksums/release-archives.json` must include the matching `vX.Y.Z` entry with both `github_tarball_sha256` and `github_zip_sha256`.
|
|
206
|
-
- Use `python3 scripts/update_release_checksums.py --tag vX.Y.Z` after the GitHub tag archives exist, commit the checksum update to `
|
|
206
|
+
- Use `python3 scripts/update_release_checksums.py --tag vX.Y.Z` after the GitHub tag archives exist, commit the checksum update, attach that file to the tagged GitHub Release as `release-archives.json`, then publish packages only after `npm run release:validate`, `npm run lint`, and `npm test` pass.
|
|
207
207
|
|
|
208
208
|
### Environment
|
|
209
209
|
|
|
@@ -265,6 +265,10 @@ cdx next
|
|
|
265
265
|
|
|
266
266
|
# Notify when the next cooling-down assistant is ready
|
|
267
267
|
cdx ready
|
|
268
|
+
|
|
269
|
+
# Inspect CDX_HOME and profile disk usage
|
|
270
|
+
cdx disk
|
|
271
|
+
cdx disk profiles --candidates
|
|
268
272
|
```
|
|
269
273
|
|
|
270
274
|
### Next-Ready Notifications
|
|
@@ -358,7 +362,10 @@ cdx history --summary --from 2026-05-01 --to 2026-05-28
|
|
|
358
362
|
| `cdx handoff <name> [--json]` | Install the current workspace context into a target session and launch it unless `--json` is used |
|
|
359
363
|
| `cdx handoff <source> <target> [--json]` | Build shared context from the source session's latest launch transcript, install it into the target session, and launch the target unless `--json` is used; supports cross-provider handoff |
|
|
360
364
|
| `cdx rmv <name> [--force] [--json]` | Remove a session and its auth data (prompts for confirmation unless `--force`) |
|
|
361
|
-
| `cdx clean [name] [--json]` | Clear launch transcript logs for one session or all sessions |
|
|
365
|
+
| `cdx clean [name] [--yes] [--json]` | Clear launch transcript logs for one session or all sessions after confirmation |
|
|
366
|
+
| `cdx clean profiles (--tmp\|--old-logs DAYS) [--yes] [--json]` | Remove explicit profile cleanup candidates after confirmation: temporary marketplace/plugin staging caches or old `.log` files |
|
|
367
|
+
| `cdx disk [profiles] [--candidates] [--json]` | Measure `CDX_HOME`; `profiles` includes per-profile breakdown, and `--candidates` reports reclaimable temporary caches and old logs with evidence |
|
|
368
|
+
| `cdx reset <name> [--yes] [--json]` | Explicitly consume one available banked Codex rate-limit reset; confirmation is required unless `--yes` is supplied |
|
|
362
369
|
| `cdx export <file> [--include-auth] [--sessions a,b] [--passphrase-env VAR\|--passphrase-stdin] [--force] [--json]` | Export sessions to a portable bundle; `--include-auth` encrypts auth data with a passphrase |
|
|
363
370
|
| `cdx import <file> [--sessions a,b] [--passphrase-env VAR\|--passphrase-stdin] [--force] [--json]` | Import sessions from a bundle into the current `CDX_HOME` |
|
|
364
371
|
| `cdx doctor [--json]` | Inspect CLI dependencies, CDX_HOME permissions, missing state, orphan profiles, and pending quarantines |
|
|
@@ -394,6 +401,8 @@ Commands with machine-readable output:
|
|
|
394
401
|
- `cdx ren ... --json`
|
|
395
402
|
- `cdx rmv ... --json`
|
|
396
403
|
- `cdx clean ... --json`
|
|
404
|
+
- `cdx disk ... --json`
|
|
405
|
+
- `cdx reset ... --json`
|
|
397
406
|
- `cdx export ... --json`
|
|
398
407
|
- `cdx import ... --json`
|
|
399
408
|
- `cdx login ... --json`
|
|
@@ -512,7 +521,7 @@ Notes:
|
|
|
512
521
|
- `--include-auth` is encrypted, requires a passphrase, and exports only provider credential files rather than full profile caches or logs.
|
|
513
522
|
- Without `--passphrase-env`, `cdx` prompts in an interactive terminal. Non-interactive callers can pass `--passphrase-stdin` to read the passphrase from stdin (one line) instead of exposing it in the child environment.
|
|
514
523
|
- `--sessions work,perso` exports or imports only a subset.
|
|
515
|
-
- `--force` allows overwriting existing destination sessions during import or replacing an existing bundle file during export.
|
|
524
|
+
- `--force` allows overwriting existing destination sessions during import or replacing an existing bundle file during export. Import refuses to overwrite existing sessions from a bundle without auth payloads unless `--allow-authless-force` is also passed.
|
|
516
525
|
- Auth bundles contain credentials. Treat them like secrets and delete them after transfer.
|
|
517
526
|
|
|
518
527
|
---
|
|
@@ -602,7 +611,68 @@ All session data lives under `CDX_HOME` (default: `~/.cdx/`):
|
|
|
602
611
|
cdx-session.log
|
|
603
612
|
```
|
|
604
613
|
|
|
605
|
-
Session names are URL-encoded when used as directory or file names. CLI command names such as `add`, `status`, and `login` are reserved and cannot be used as session names.
|
|
614
|
+
Session names are URL-encoded when used as directory or file names. CLI command names such as `add`, `disk`, `status`, and `login` are reserved and cannot be used as new session names.
|
|
615
|
+
|
|
616
|
+
### Disk maintenance
|
|
617
|
+
|
|
618
|
+
Use `cdx disk` for a total `CDX_HOME` measurement, and `cdx disk profiles` for the `profiles/` total plus a per-profile breakdown.
|
|
619
|
+
|
|
620
|
+
In an interactive terminal, long scans report their current stage and per-profile progress on stderr. JSON and redirected output remain free of progress messages.
|
|
621
|
+
|
|
622
|
+
Text output uses aligned summary tables with profile size, share of total space, and reclaimable space. Candidate details are grouped by profile with separate size, type, risk, and evidence columns.
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
cdx disk
|
|
626
|
+
cdx disk profiles
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
To find cleanup candidates without deleting anything:
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
cdx disk profiles --candidates
|
|
633
|
+
cdx disk profiles --candidates --json
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Candidate evidence includes profile name, path, size, risk, reason, and metadata such as modified time or old-log file counts. The current cleanup candidates are intentionally limited to:
|
|
637
|
+
|
|
638
|
+
- temporary marketplace/plugin staging caches under `profiles/*/.tmp/`
|
|
639
|
+
- `.log` files older than the requested age inside profile `log/` directories
|
|
640
|
+
|
|
641
|
+
`cdx` also runs a passive disk cleanup check at most once per day on advisory commands such as `cdx` and `cdx status`. It writes the check timestamp and latest measurements to `~/.cdx/state/disk-cleanup-check.json`. A warning is shown only when at least one threshold is met:
|
|
642
|
+
|
|
643
|
+
- `CDX_HOME` uses 10 GB or more
|
|
644
|
+
- cleanup candidates can reclaim 1 GB or more
|
|
645
|
+
- temporary cache candidates can reclaim 500 MB or more
|
|
646
|
+
- old log candidates can reclaim 500 MB or more
|
|
647
|
+
- one profile is 2 GB or more, or one profile is at least 25% of `profiles/` when `profiles/` is already 1 GB or more
|
|
648
|
+
|
|
649
|
+
The passive warning is read-only and points to `cdx disk profiles --candidates`; it never deletes files.
|
|
650
|
+
|
|
651
|
+
Apply cleanup only with explicit actions:
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
cdx clean profiles --tmp
|
|
655
|
+
cdx clean profiles --old-logs 30d
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
`--tmp` removes temporary marketplace/plugin clone/backup staging directories. `--old-logs 30d` removes only `.log` files older than 30 days. The commands do not remove `auth.json`, `config.toml`, `sessions/`, SQLite state, installed `plugins/`, `skills/`, or credentials.
|
|
659
|
+
|
|
660
|
+
All `cdx clean` actions require interactive confirmation before any deletion or log truncation begins. Non-interactive scripts must pass `--yes` explicitly.
|
|
661
|
+
|
|
662
|
+
The cleanup action is selected only when `--tmp` or `--old-logs` is present. This keeps `cdx clean profiles` available for an existing session named `profiles`. If any candidate or old log cannot be removed, cleanup stops with a non-zero error that identifies the affected path; it does not report the operation as successful.
|
|
663
|
+
|
|
664
|
+
### Banked Codex resets
|
|
665
|
+
|
|
666
|
+
Eligible Codex accounts expose manually redeemable rate-limit resets through the Codex app-server. `cdx status` shows their available count in the `RESETS` column; `cdx status <name>` also shows the nearest known expiration, and JSON status includes the available reset details supplied by Codex.
|
|
667
|
+
|
|
668
|
+
Activation is always explicit:
|
|
669
|
+
|
|
670
|
+
```bash
|
|
671
|
+
cdx reset <name>
|
|
672
|
+
cdx reset <name> --yes --json
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
Without `--yes`, an interactive confirmation is required. `cdx` sends an idempotency key, consumes at most one available reset, and refreshes the session status after a successful activation. It never activates a reset from `cdx status` or any background check.
|
|
606
676
|
|
|
607
677
|
---
|
|
608
678
|
|
package/bin/cdx
CHANGED
|
@@ -3,21 +3,12 @@
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
ROOT = Path(__file__).resolve().parent.parent
|
|
8
7
|
if str(ROOT) not in sys.path:
|
|
9
8
|
sys.path.insert(0, str(ROOT))
|
|
10
9
|
|
|
11
|
-
from src.cli import
|
|
12
|
-
from src.errors import CdxError # noqa: E402
|
|
10
|
+
from src.cli import cli_entry # noqa: E402
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
if __name__ == "__main__":
|
|
16
|
-
|
|
17
|
-
raise SystemExit(main(sys.argv[1:]))
|
|
18
|
-
except CdxError as error:
|
|
19
|
-
if wants_json(sys.argv[1:]):
|
|
20
|
-
sys.stderr.write(f"{format_json_error(error)}\n")
|
|
21
|
-
else:
|
|
22
|
-
sys.stderr.write(f"{format_error(error)}\n")
|
|
23
|
-
raise SystemExit(error.exit_code)
|
|
14
|
+
cli_entry()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# CDX Manager 0.10.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Inspect `CDX_HOME` and per-profile disk usage with readable, progress-aware reports.
|
|
6
|
+
- Find evidence-backed cleanup candidates and reclaim space through confirmed actions.
|
|
7
|
+
- Display and explicitly activate banked Codex rate-limit resets.
|
|
8
|
+
|
|
9
|
+
## Changes
|
|
10
|
+
|
|
11
|
+
### Disk usage and cleanup
|
|
12
|
+
|
|
13
|
+
`cdx disk` measures total `CDX_HOME` usage. `cdx disk profiles` adds an aligned per-profile table with size and share of total space, while `--candidates` adds reclaimable totals and evidence grouped by profile.
|
|
14
|
+
|
|
15
|
+
Interactive scans report their current stage and profile count on stderr so large profiles no longer appear stalled. JSON and redirected output remain unchanged.
|
|
16
|
+
|
|
17
|
+
Cleanup candidates are intentionally limited to temporary marketplace/plugin staging directories and old `.log` files. `cdx clean profiles --tmp` and `cdx clean profiles --old-logs DAYS` require confirmation before deletion; all other `cdx clean` log-truncation actions now require confirmation as well. Non-interactive automation must opt in with `--yes`.
|
|
18
|
+
|
|
19
|
+
A passive read-only check runs at most once per day and warns when documented total, reclaimable, category, or large-profile thresholds are reached. It never removes files automatically.
|
|
20
|
+
|
|
21
|
+
### Banked Codex resets
|
|
22
|
+
|
|
23
|
+
Eligible Codex accounts now show banked rate-limit reset counts in `cdx status`. Detailed JSON includes reset identifiers, labels, grant timestamps, and expiration timestamps when Codex provides them.
|
|
24
|
+
|
|
25
|
+
`cdx reset <name>` consumes one reset through Codex's idempotent reset-credit endpoint, requires confirmation unless `--yes` is supplied, and refreshes status after activation. Status checks never consume resets automatically.
|
|
26
|
+
|
|
27
|
+
### Compatibility and safeguards
|
|
28
|
+
|
|
29
|
+
`disk` and `reset` are reserved for new session names. Existing sessions named `profiles` remain compatible with `cdx clean profiles`; profile-wide cleanup is selected only when `--tmp` or `--old-logs` is present.
|
|
30
|
+
|
|
31
|
+
Cleanup failures now stop with a non-zero error naming the affected path instead of silently reporting zero bytes removed.
|
|
32
|
+
|
|
33
|
+
## Validation
|
|
34
|
+
|
|
35
|
+
- `npm run release:validate`
|
|
36
|
+
- `npm run lint`
|
|
37
|
+
- `npm test`
|
|
38
|
+
- `logics-manager lint --require-status`
|
|
39
|
+
- `logics-manager audit`
|
|
40
|
+
- `git diff --check`
|
|
41
|
+
- `npm --cache /private/tmp/cdx-npm-cache pack --dry-run`
|
|
42
|
+
- `python -m build`
|
|
43
|
+
- `python -m twine check dist/*`
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# CDX Manager 0.11.0
|
|
2
|
+
|
|
3
|
+
## Highlights
|
|
4
|
+
|
|
5
|
+
- Fixed Codex structured status parsing so five-hour and weekly reset windows stay mapped to the correct columns.
|
|
6
|
+
- Hardened backup import, provider auth probing, release verification, and Windows launcher generation.
|
|
7
|
+
- Closed the July 2026 review remediation corpus and follow-up Logics workflow with release-ready validation.
|
|
8
|
+
|
|
9
|
+
## Changes
|
|
10
|
+
|
|
11
|
+
### Codex status reset windows
|
|
12
|
+
|
|
13
|
+
Structured Codex status payloads now preserve the distinction between the five-hour and weekly reset timestamps. `cdx status` no longer mirrors the weekly reset into the five-hour reset column, or the reverse, when provider output includes both windows.
|
|
14
|
+
|
|
15
|
+
### Safer session import and credentials handling
|
|
16
|
+
|
|
17
|
+
`cdx import --force` refuses to overwrite existing sessions from bundles without auth payloads unless `--allow-authless-force` is explicitly supplied.
|
|
18
|
+
|
|
19
|
+
Bundle import now validates selected profile paths, base64 payloads, malformed profile collections, and non-object profile entries before touching existing session profiles. Existing profiles are renamed aside during force import and restored if a per-session import fails.
|
|
20
|
+
|
|
21
|
+
### Provider auth reliability
|
|
22
|
+
|
|
23
|
+
Provider auth probes are bounded by a 15 second timeout. Timeouts now surface as a degraded authentication state instead of being persisted as `logged_out`.
|
|
24
|
+
|
|
25
|
+
Codex interactive launches wait on the per-auth-home lock with a bounded retry instead of running unlocked while another process may be rotating OAuth credentials.
|
|
26
|
+
|
|
27
|
+
Stored `reasoning_effort` and `power` launch settings now clear each other correctly, so setting one cannot leave the other silently shadowing it.
|
|
28
|
+
|
|
29
|
+
### CLI robustness and release hardening
|
|
30
|
+
|
|
31
|
+
`cdx history` skips corrupt JSONL lines, `cdx status` tolerates sessions removed during a concurrent scan, `cdx clean profiles` routes profile cleanup flags consistently, `cdx disk --candidates` validates arguments before scanning, and `cdx view --json` now reports a proper failure when the Logics viewer is unavailable.
|
|
32
|
+
|
|
33
|
+
The npm launcher routes through the same `cli_entry()` path as the Python entrypoint. Standalone installers and publish workflows now use tagged GitHub Release checksum assets rather than main-branch checksum metadata, and `CDX_ALLOW_UNVERIFIED=1` prints a prominent warning before continuing.
|
|
34
|
+
|
|
35
|
+
The standalone Windows installer now generates `cdx.cmd` with the installed version directory in the launcher path.
|
|
36
|
+
|
|
37
|
+
### Logics documentation
|
|
38
|
+
|
|
39
|
+
The July 2026 review remediation corpus and post-review follow-up corpus are closed with implementation reports, validation evidence, and a clean Logics audit.
|
|
40
|
+
|
|
41
|
+
## Validation
|
|
42
|
+
|
|
43
|
+
- `npm run release:validate`
|
|
44
|
+
- `npm run lint`
|
|
45
|
+
- `npm test`
|
|
46
|
+
- `logics-manager lint --require-status`
|
|
47
|
+
- `logics-manager audit`
|
|
48
|
+
- `git diff --check`
|
|
49
|
+
- `npm --cache /private/tmp/cdx-npm-cache pack --dry-run`
|
|
50
|
+
- `python -m build`
|
|
51
|
+
- `python -m twine check dist/*`
|
|
@@ -128,6 +128,14 @@
|
|
|
128
128
|
"v0.9.15": {
|
|
129
129
|
"github_tarball_sha256": "08e6c5a3459fdd65d1f6085ca03a3614f07b4bf44c57a995a3ef47446aa70482",
|
|
130
130
|
"github_zip_sha256": "c8ac01f4a65e85b417f5eba5139868ab17b8f0952bf99f17f0a79f73ef0f36d6"
|
|
131
|
+
},
|
|
132
|
+
"v0.9.16": {
|
|
133
|
+
"github_tarball_sha256": "0876509c201485824f6e5fe7b4a96ceb41cc68279fbe6dda4891864cf5be93ec",
|
|
134
|
+
"github_zip_sha256": "08072957a0421d257cecfa8bed73cceee80d1c8857c59ac45378ac8ce3e0362d"
|
|
135
|
+
},
|
|
136
|
+
"v0.10.0": {
|
|
137
|
+
"github_tarball_sha256": "20c473f4b17806d565c454ad4aa28758433665d8431251ebb937ab6a909e4adb",
|
|
138
|
+
"github_zip_sha256": "b6a7be359d8dc2a11d8c77749878875419fabd7cd5a6951502dec09d7791e211"
|
|
131
139
|
}
|
|
132
140
|
}
|
|
133
141
|
}
|
package/install.ps1
CHANGED
|
@@ -9,13 +9,7 @@ $ErrorActionPreference = "Stop"
|
|
|
9
9
|
|
|
10
10
|
$repo = "AlexAgo83/cdx-manager"
|
|
11
11
|
if (-not $ChecksumsUrl) {
|
|
12
|
-
$ChecksumsUrl =
|
|
13
|
-
}
|
|
14
|
-
$defaultChecksumsUrl = "https://raw.githubusercontent.com/$repo/main/checksums/release-archives.json"
|
|
15
|
-
$checksumsApiUrl = if ($env:CDX_CHECKSUMS_API_URL) {
|
|
16
|
-
$env:CDX_CHECKSUMS_API_URL
|
|
17
|
-
} else {
|
|
18
|
-
"https://api.github.com/repos/$repo/contents/checksums/release-archives.json?ref=main"
|
|
12
|
+
$ChecksumsUrl = $null
|
|
19
13
|
}
|
|
20
14
|
|
|
21
15
|
function Has-Command {
|
|
@@ -45,10 +39,16 @@ if ($Version.StartsWith("v")) {
|
|
|
45
39
|
$tag = "v$Version"
|
|
46
40
|
}
|
|
47
41
|
|
|
42
|
+
$defaultChecksumsUrl = "https://github.com/$repo/releases/download/$tag/release-archives.json"
|
|
43
|
+
if (-not $ChecksumsUrl) {
|
|
44
|
+
$ChecksumsUrl = $defaultChecksumsUrl
|
|
45
|
+
}
|
|
46
|
+
|
|
48
47
|
$tmpRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("cdx-install-" + [guid]::NewGuid().ToString("N"))
|
|
49
48
|
$archivePath = Join-Path $tmpRoot "cdx-manager.zip"
|
|
50
49
|
$extractRoot = Join-Path $tmpRoot "extract"
|
|
51
|
-
$
|
|
50
|
+
$versionDir = $tag.TrimStart("v")
|
|
51
|
+
$targetDir = Join-Path $installRoot $versionDir
|
|
52
52
|
$archiveUrl = "https://github.com/$repo/archive/refs/tags/$tag.zip"
|
|
53
53
|
|
|
54
54
|
New-Item -ItemType Directory -Force -Path $tmpRoot, $extractRoot, $binDir, $installRoot | Out-Null
|
|
@@ -62,15 +62,6 @@ try {
|
|
|
62
62
|
} catch {
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
if ((-not $Sha256) -and ($ChecksumsUrl -eq $defaultChecksumsUrl)) {
|
|
66
|
-
try {
|
|
67
|
-
$checksumsResponse = Invoke-RestMethod -Uri $checksumsApiUrl
|
|
68
|
-
$checksumsJson = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($checksumsResponse.content))
|
|
69
|
-
$checksums = $checksumsJson | ConvertFrom-Json
|
|
70
|
-
$Sha256 = $checksums.releases.$tag.github_zip_sha256
|
|
71
|
-
} catch {
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
65
|
if ($Sha256) {
|
|
75
66
|
$actualSha256 = (Get-FileHash -Algorithm SHA256 -Path $archivePath).Hash.ToLowerInvariant()
|
|
76
67
|
if ($actualSha256 -ne $Sha256.ToLowerInvariant()) {
|
|
@@ -78,7 +69,9 @@ try {
|
|
|
78
69
|
}
|
|
79
70
|
} else {
|
|
80
71
|
if ($env:CDX_ALLOW_UNVERIFIED -eq "1") {
|
|
81
|
-
Write-Warning "
|
|
72
|
+
Write-Warning "Installing $tag without checksum verification."
|
|
73
|
+
Write-Warning "CDX_ALLOW_UNVERIFIED=1 disables archive integrity checks."
|
|
74
|
+
Write-Warning "Continue only if you trust the download source."
|
|
82
75
|
} else {
|
|
83
76
|
throw "cdx install: no official checksum available for $tag. Set CDX_ALLOW_UNVERIFIED=1 to install without checksum verification."
|
|
84
77
|
}
|
|
@@ -99,7 +92,7 @@ try {
|
|
|
99
92
|
$launcherPath = Join-Path $binDir "cdx.cmd"
|
|
100
93
|
$launcher = @"
|
|
101
94
|
@echo off
|
|
102
|
-
set SCRIPT=%~dp0..\versions\$
|
|
95
|
+
set SCRIPT=%~dp0..\versions\$versionDir\bin\cdx
|
|
103
96
|
where py >nul 2>nul
|
|
104
97
|
if %ERRORLEVEL%==0 (
|
|
105
98
|
py -3 "%SCRIPT%" %*
|
package/install.sh
CHANGED
|
@@ -6,9 +6,6 @@ VERSION="${CDX_VERSION:-}"
|
|
|
6
6
|
PREFIX="${PREFIX:-$HOME/.local}"
|
|
7
7
|
BIN_DIR="${BIN_DIR:-$PREFIX/bin}"
|
|
8
8
|
INSTALL_ROOT="${CDX_INSTALL_ROOT:-$PREFIX/share/cdx-manager}"
|
|
9
|
-
DEFAULT_CHECKSUMS_URL="https://raw.githubusercontent.com/$REPO/main/checksums/release-archives.json"
|
|
10
|
-
CHECKSUMS_URL="${CDX_CHECKSUMS_URL:-$DEFAULT_CHECKSUMS_URL}"
|
|
11
|
-
CHECKSUMS_API_URL="${CDX_CHECKSUMS_API_URL:-https://api.github.com/repos/$REPO/contents/checksums/release-archives.json?ref=main}"
|
|
12
9
|
|
|
13
10
|
need() {
|
|
14
11
|
if ! command -v "$1" >/dev/null 2>&1; then
|
|
@@ -53,27 +50,6 @@ if value:
|
|
|
53
50
|
' "$1"
|
|
54
51
|
}
|
|
55
52
|
|
|
56
|
-
resolve_expected_sha256_from_api() {
|
|
57
|
-
curl -fsSL "$CHECKSUMS_API_URL" |
|
|
58
|
-
python3 -c '
|
|
59
|
-
import base64
|
|
60
|
-
import json
|
|
61
|
-
import sys
|
|
62
|
-
|
|
63
|
-
tag = sys.argv[1]
|
|
64
|
-
try:
|
|
65
|
-
response = json.load(sys.stdin)
|
|
66
|
-
payload = json.loads(base64.b64decode(response.get("content") or b"").decode("utf-8"))
|
|
67
|
-
except Exception:
|
|
68
|
-
raise SystemExit(1)
|
|
69
|
-
|
|
70
|
-
release = (payload.get("releases") or {}).get(tag) or {}
|
|
71
|
-
value = release.get("github_tarball_sha256")
|
|
72
|
-
if value:
|
|
73
|
-
print(value)
|
|
74
|
-
' "$1"
|
|
75
|
-
}
|
|
76
|
-
|
|
77
53
|
if [ -z "$VERSION" ]; then
|
|
78
54
|
VERSION="$(
|
|
79
55
|
curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" |
|
|
@@ -86,6 +62,9 @@ case "$VERSION" in
|
|
|
86
62
|
*) TAG="v$VERSION" ;;
|
|
87
63
|
esac
|
|
88
64
|
|
|
65
|
+
DEFAULT_CHECKSUMS_URL="https://github.com/$REPO/releases/download/$TAG/release-archives.json"
|
|
66
|
+
CHECKSUMS_URL="${CDX_CHECKSUMS_URL:-$DEFAULT_CHECKSUMS_URL}"
|
|
67
|
+
|
|
89
68
|
TMP_DIR="$(mktemp -d)"
|
|
90
69
|
cleanup() {
|
|
91
70
|
rm -rf "$TMP_DIR"
|
|
@@ -99,10 +78,6 @@ EXPECTED_SHA256="${CDX_SHA256:-}"
|
|
|
99
78
|
if [ -z "$EXPECTED_SHA256" ]; then
|
|
100
79
|
EXPECTED_SHA256="$(resolve_expected_sha256 "$TAG" 2>/dev/null || true)"
|
|
101
80
|
fi
|
|
102
|
-
if [ -z "$EXPECTED_SHA256" ] && [ "$CHECKSUMS_URL" = "$DEFAULT_CHECKSUMS_URL" ]; then
|
|
103
|
-
EXPECTED_SHA256="$(resolve_expected_sha256_from_api "$TAG" 2>/dev/null || true)"
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
81
|
if [ -n "$EXPECTED_SHA256" ]; then
|
|
107
82
|
ACTUAL_SHA256="$(sha256_file "$TMP_DIR/cdx-manager.tar.gz")"
|
|
108
83
|
if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
|
|
@@ -113,7 +88,9 @@ if [ -n "$EXPECTED_SHA256" ]; then
|
|
|
113
88
|
fi
|
|
114
89
|
else
|
|
115
90
|
if [ "${CDX_ALLOW_UNVERIFIED:-}" = "1" ]; then
|
|
116
|
-
echo "cdx install:
|
|
91
|
+
echo "cdx install: WARNING: installing $TAG without checksum verification." >&2
|
|
92
|
+
echo "cdx install: WARNING: CDX_ALLOW_UNVERIFIED=1 disables archive integrity checks." >&2
|
|
93
|
+
echo "cdx install: WARNING: continue only if you trust the download source." >&2
|
|
117
94
|
else
|
|
118
95
|
echo "cdx install: no official checksum available for $TAG" >&2
|
|
119
96
|
echo "Set CDX_ALLOW_UNVERIFIED=1 to install without checksum verification." >&2
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
package/src/claude_refresh.py
CHANGED
|
@@ -48,40 +48,24 @@ def _refresh_claude_sessions(service, refresh_fn=None, target_names=None, force=
|
|
|
48
48
|
errors = []
|
|
49
49
|
results = {}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
import asyncio
|
|
51
|
+
threads = []
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
try:
|
|
71
|
-
usage = refresh_fn(s)
|
|
72
|
-
if inspect.isawaitable(usage):
|
|
73
|
-
raise CdxError("Claude refresh function returned an awaitable from a sync callable.")
|
|
74
|
-
if usage:
|
|
75
|
-
results[s["name"]] = usage
|
|
76
|
-
except Exception as e:
|
|
77
|
-
errors.append({"session": s["name"], "error": e})
|
|
78
|
-
|
|
79
|
-
for s in claude_sessions:
|
|
80
|
-
t = threading.Thread(target=fetch, args=(s,), daemon=True)
|
|
81
|
-
threads.append(t)
|
|
82
|
-
t.start()
|
|
83
|
-
for t in threads:
|
|
84
|
-
t.join(timeout=10)
|
|
53
|
+
def fetch(s):
|
|
54
|
+
try:
|
|
55
|
+
usage = refresh_fn(s)
|
|
56
|
+
if inspect.isawaitable(usage):
|
|
57
|
+
raise CdxError("Claude refresh function returned an awaitable from a sync callable.")
|
|
58
|
+
if usage:
|
|
59
|
+
results[s["name"]] = usage
|
|
60
|
+
except Exception as e:
|
|
61
|
+
errors.append({"session": s["name"], "error": e})
|
|
62
|
+
|
|
63
|
+
for s in claude_sessions:
|
|
64
|
+
t = threading.Thread(target=fetch, args=(s,), daemon=True)
|
|
65
|
+
threads.append(t)
|
|
66
|
+
t.start()
|
|
67
|
+
for t in threads:
|
|
68
|
+
t.join(timeout=10)
|
|
85
69
|
|
|
86
70
|
# A worker that outlived its join can still insert into results/errors;
|
|
87
71
|
# snapshot both so late writes can't mutate what we iterate.
|