cdx-manager 0.25.7 → 0.25.8
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_8.md +15 -0
- package/changelogs/CHANGELOGS_UNRELEASED.md +6 -0
- package/checksums/release-archives.json +11 -0
- package/docs/operations.md +39 -0
- package/docs/sessions-and-notifications.md +1 -1
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/workspace_sandbox.py +21 -8
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.8
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# CDX Manager 0.25.8
|
|
2
|
+
|
|
3
|
+
Release date: 2026-11-02
|
|
4
|
+
|
|
5
|
+
This patch release restores Git history and RTK access in isolated workspaces.
|
|
6
|
+
|
|
7
|
+
## Fixes
|
|
8
|
+
|
|
9
|
+
- Restore read-only Git history access in isolated local and remote workspaces, including linked worktrees with packed objects and refs. Keep Git metadata read-only and exclude host configuration, hooks, remotes, and credentials. (#91)
|
|
10
|
+
- Expose the installed RTK binary in isolated launches and persist its savings history in a dedicated shared cache, separate from the operator's normal RTK history. (#91)
|
|
11
|
+
|
|
12
|
+
## Maintenance
|
|
13
|
+
|
|
14
|
+
- Record tray companion checksums for v0.25.7. (`31b7ecfb8f8189f29b01aaa88f9acf866acccd19`)
|
|
15
|
+
- Record release archive checksums for v0.25.7. (`03d339b9e93e2d7d917df6e614132390ce4436fe`)
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
## Isolated mission Git and RTK
|
|
4
|
+
|
|
5
|
+
- Give local and remote isolated linked worktrees a read-only Git view with their own HEAD/index and shared objects/refs, without traversing private host parents or exposing repository/global configuration, hooks, SSH keys or Git push credentials. Preserve supervisor-owned commits and pushes.
|
|
6
|
+
- Add the mounted operator `~/.local/bin` to sandbox PATH and persist RTK savings in the execution host's shared cache at `/cache/rtk/history.db`, overriding inaccessible host history paths for isolated launches only.
|
|
7
|
+
- Cover real Git commands against selected metadata, local and shipped worker launch environments, and an opt-in required bubblewrap acceptance check for Git, RTK history writes, review mode and an unreadable synthetic SSH key. Document the namespace requirement and sandbox history location.
|
|
8
|
+
|
|
3
9
|
## Truthful workstation updates
|
|
4
10
|
|
|
5
11
|
- 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`.
|
|
@@ -760,6 +760,17 @@
|
|
|
760
760
|
"x86_64-pc-windows-msvc": "5c3c4be1dcf6801ed0ed73bef8840deb379e2724d9728f983498d0fe5a99c542",
|
|
761
761
|
"x86_64-unknown-linux-musl": "ba91c1378b78e529da3af35c7e649ed2063ba27963ef91949f1aabe9e3fe2a0f"
|
|
762
762
|
}
|
|
763
|
+
},
|
|
764
|
+
"v0.25.7": {
|
|
765
|
+
"github_tarball_sha256": "e9a943ca212e0706f5a3ad29d9be99b8bf5293836d4f082dddd797e122475310",
|
|
766
|
+
"github_zip_sha256": "19eb0266ed35aae2386fd9d90079a7be5dbc44a3b44249615c244fc7c4f7d85f",
|
|
767
|
+
"tray_assets": {
|
|
768
|
+
"aarch64-apple-darwin": "9fa198f0133ac40747fb00f4353af174b45b550ebef4662398b84aa9459e2388",
|
|
769
|
+
"aarch64-unknown-linux-musl": "c4ccba259e7f910bd5a2ce8abfa2045ba4ad9b975da7dea2c8dfc0ba1bd5bbfc",
|
|
770
|
+
"x86_64-apple-darwin": "1341e59d8da3489368e22c85c9ea3d974254c810d3b68077b2e1b02d2c9aee5a",
|
|
771
|
+
"x86_64-pc-windows-msvc": "be2e6ff8607351019447c6fbf0622254c2f8d8db81581007af71b74932e37f50",
|
|
772
|
+
"x86_64-unknown-linux-musl": "32de07569929ade136cf75ed8f0716e0f3b96a9c53c6632c628e13782d223518"
|
|
773
|
+
}
|
|
763
774
|
}
|
|
764
775
|
}
|
|
765
776
|
}
|
package/docs/operations.md
CHANGED
|
@@ -242,6 +242,45 @@ credential sync.
|
|
|
242
242
|
- **On Windows, `doctor` warns that `script` is missing** — this is expected on many setups. Codex still launches, but transcript capture stays disabled unless you point `CDX_SCRIPT_BIN` to a compatible wrapper.
|
|
243
243
|
|
|
244
244
|
|
|
245
|
+
### Git and RTK in isolated workspaces
|
|
246
|
+
|
|
247
|
+
Local and remote `cdx run --isolate-workspace` use the same sandbox implementation.
|
|
248
|
+
For a linked Git worktree, CDX builds a read-only Git view at `/home/agent/.git`:
|
|
249
|
+
the mission's HEAD and index, plus the common objects, refs, packed refs, shallow
|
|
250
|
+
boundary and split-index files. `GIT_DIR`, `GIT_COMMON_DIR` and `GIT_WORK_TREE`
|
|
251
|
+
select that view without traversing the operator's private home directories.
|
|
252
|
+
`git log`, `show`, `diff`, `status`, `blame`, `branch` and `rev-parse` can read
|
|
253
|
+
the mission history, including packed objects and refs. Review runs also keep
|
|
254
|
+
checkout files read-only. Git metadata stays read-only in writable missions,
|
|
255
|
+
as before: committing and pushing remain the supervising mission flow's job.
|
|
256
|
+
|
|
257
|
+
Host repository configuration, hooks, other worktrees, global Git configuration,
|
|
258
|
+
SSH keys, credential helpers and token environment variables are not added.
|
|
259
|
+
The view has no configured remotes. Existing provider authentication rules are
|
|
260
|
+
unchanged; this does not grant Git push credentials.
|
|
261
|
+
|
|
262
|
+
The sandbox appends the mounted operator `~/.local/bin` to PATH, including for
|
|
263
|
+
noninteractive remote launches whose PATH omits it. An installed `rtk` is thus
|
|
264
|
+
available without installing a second copy. Isolated launches override
|
|
265
|
+
`RTK_DB_PATH` with `/cache/rtk/history.db`, backed by
|
|
266
|
+
`~/.cdx/shared-cache/rtk/history.db` on the execution host. Savings persist
|
|
267
|
+
across isolated attempts; the operator's normal RTK history is not mounted.
|
|
268
|
+
Inspect them with `RTK_DB_PATH="$HOME/.cdx/shared-cache/rtk/history.db" rtk gain`
|
|
269
|
+
on that host. Non-isolated launches keep their normal history selection.
|
|
270
|
+
|
|
271
|
+
Run the real confinement acceptance check on a Linux host with bubblewrap and
|
|
272
|
+
RTK installed (it uses disposable fixtures and synthetic secrets):
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
CDX_REQUIRE_SANDBOX_TESTS=1 python3 -m pytest -q test/test_workspace_sandbox_tools_py.py
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
It exercises the local and shipped worker implementations, writable and review
|
|
279
|
+
checkouts, Git history commands, RTK database writes, and denial of a synthetic
|
|
280
|
+
SSH key outside the checkout. The required mode fails rather than skipping
|
|
281
|
+
when nested namespaces or RTK are unavailable. Default test runs skip only
|
|
282
|
+
those unavailable integration cases; copied-metadata Git checks still run.
|
|
283
|
+
|
|
245
284
|
### Playwright in isolated workspaces
|
|
246
285
|
|
|
247
286
|
Isolated preparation and provider environments force `PLAYWRIGHT_SKIP_BROWSER_GC=1`.
|
|
@@ -154,7 +154,7 @@ cdx power all default
|
|
|
154
154
|
cdx model provider:ollama default
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
-
`--model` maps to Codex `--model`, Claude `--model`, and Ollama `ollama run <model>`. `--power` maps to Codex `model_reasoning_effort` and Claude `--effort`; supported values are `minimal`, `low`, `medium`, `high`, and `xhigh`. `--permission` maps to provider-native permission flags. Codex Fast mode is separate from reasoning effort: `--fast on` opts a Codex session into the Codex Fast service tier, while new sessions, `--fast off`, and default launches force the non-Fast `flex` tier. Use `--power low` when you want low reasoning effort without enabling Codex Fast credits. Existing legacy sessions that stored `fast=on` before this split continue to behave as low effort unless the user explicitly sets `--fast on` again. `--priority` is a 0..100 selector preference used as a tie-breaker after readiness and availability. `--policy use|ask-first|never` (default `use`) says whether cdx may pick an account on your behalf: `cdx next`, `cdx select`, `cdx run --provider` and run failover only ever choose `use` accounts; `ask-first` accounts are offered by `cdx rescue` with a confirmation, `never` accounts are not offered at all. Naming an account explicitly (`cdx <name>`, `cdx run <name>`) is always allowed. `--rtk on` adds standing guidance that encourages assistants to use RTK (`rtk <command>`) for noisy terminal commands when RTK is available, while keeping raw commands for exact output. Logics guidance is auto-enabled when `logics-manager` is available; use `--logics off` to disable that guidance for a session, or `--logics on` to pin it explicitly. This guidance is passed as instructions, never as a first message: Claude receives it through `--append-system-prompt` and Codex through `-c developer_instructions=...`, appended after any `developer_instructions` already set in the profile's `config.toml` (on Python older than 3.11 without `tomli`, a profile that sets its own is left untouched and gets no cdx guidance). Launching or resuming a session therefore never submits a turn on your behalf. Antigravity and Ollama have no instruction channel and receive no guidance. Whatever the `--rtk` setting, every launch, resume and `cdx run` sets `RTK_DB_PATH` to the rtk history of your real home (`~/Library/Application Support/rtk/history.db` on macOS, `~/.local/share/rtk/history.db` on Linux, `%LOCALAPPDATA%\rtk\history.db` on Windows), so `rtk gain` in your own shell counts what every account saved instead of each profile keeping its own; an `RTK_DB_PATH` you set yourself is kept. If you also pass `--append-system-prompt` through `--extra-args`, Claude receives the option twice; prefer putting your own text in the profile's `CLAUDE.md`.
|
|
157
|
+
`--model` maps to Codex `--model`, Claude `--model`, and Ollama `ollama run <model>`. `--power` maps to Codex `model_reasoning_effort` and Claude `--effort`; supported values are `minimal`, `low`, `medium`, `high`, and `xhigh`. `--permission` maps to provider-native permission flags. Codex Fast mode is separate from reasoning effort: `--fast on` opts a Codex session into the Codex Fast service tier, while new sessions, `--fast off`, and default launches force the non-Fast `flex` tier. Use `--power low` when you want low reasoning effort without enabling Codex Fast credits. Existing legacy sessions that stored `fast=on` before this split continue to behave as low effort unless the user explicitly sets `--fast on` again. `--priority` is a 0..100 selector preference used as a tie-breaker after readiness and availability. `--policy use|ask-first|never` (default `use`) says whether cdx may pick an account on your behalf: `cdx next`, `cdx select`, `cdx run --provider` and run failover only ever choose `use` accounts; `ask-first` accounts are offered by `cdx rescue` with a confirmation, `never` accounts are not offered at all. Naming an account explicitly (`cdx <name>`, `cdx run <name>`) is always allowed. `--rtk on` adds standing guidance that encourages assistants to use RTK (`rtk <command>`) for noisy terminal commands when RTK is available, while keeping raw commands for exact output. Logics guidance is auto-enabled when `logics-manager` is available; use `--logics off` to disable that guidance for a session, or `--logics on` to pin it explicitly. This guidance is passed as instructions, never as a first message: Claude receives it through `--append-system-prompt` and Codex through `-c developer_instructions=...`, appended after any `developer_instructions` already set in the profile's `config.toml` (on Python older than 3.11 without `tomli`, a profile that sets its own is left untouched and gets no cdx guidance). Launching or resuming a session therefore never submits a turn on your behalf. Antigravity and Ollama have no instruction channel and receive no guidance. Whatever the `--rtk` setting, every launch, resume and `cdx run` sets `RTK_DB_PATH` to the rtk history of your real home (`~/Library/Application Support/rtk/history.db` on macOS, `~/.local/share/rtk/history.db` on Linux, `%LOCALAPPDATA%\rtk\history.db` on Windows), so `rtk gain` in your own shell counts what every account saved instead of each profile keeping its own; an `RTK_DB_PATH` you set yourself is kept. Isolated workspace runs instead use the execution host's shared-cache RTK database at `/cache/rtk/history.db`; see [Git and RTK in isolated workspaces](operations.md#git-and-rtk-in-isolated-workspaces). If you also pass `--append-system-prompt` through `--extra-args`, Claude receives the option twice; prefer putting your own text in the profile's `CLAUDE.md`.
|
|
158
158
|
|
|
159
159
|
## Terminal Titles
|
|
160
160
|
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
package/src/workspace_sandbox.py
CHANGED
|
@@ -71,12 +71,14 @@ def private_auth_home(auth):
|
|
|
71
71
|
def clean_env(source: dict) -> dict:
|
|
72
72
|
allowed = ("PATH", "LANG", "LC_ALL", "TERM", "TZ")
|
|
73
73
|
env = {key: source[key] for key in allowed if key in source}
|
|
74
|
+
env["PATH"] = source.get("PATH", os.defpath) + os.pathsep + str(Path.home() / ".local/bin")
|
|
74
75
|
env.update(HOME="/home/agent", XDG_CONFIG_HOME="/home/agent/.config",
|
|
75
76
|
XDG_CACHE_HOME="/cache", GIT_CONFIG_NOSYSTEM="1",
|
|
76
77
|
GIT_CONFIG_GLOBAL="/dev/null", GIT_TERMINAL_PROMPT="0", GIT_OPTIONAL_LOCKS="0",
|
|
77
78
|
GIT_CONFIG_COUNT="1", GIT_CONFIG_KEY_0="credential.helper", GIT_CONFIG_VALUE_0="",
|
|
78
79
|
GH_CONFIG_DIR="/home/agent/.config/gh", NPM_CONFIG_CACHE="/cache/npm",
|
|
79
80
|
PIP_CACHE_DIR="/cache/pip", UV_CACHE_DIR="/cache/uv",
|
|
81
|
+
RTK_DB_PATH="/cache/rtk/history.db",
|
|
80
82
|
# Cache users have different mount paths; their GC cannot identify each other's browsers.
|
|
81
83
|
PLAYWRIGHT_BROWSERS_PATH="/cache/playwright", PLAYWRIGHT_SKIP_BROWSER_GC="1", CI="1")
|
|
82
84
|
return env
|
|
@@ -85,7 +87,8 @@ def clean_env(source: dict) -> dict:
|
|
|
85
87
|
def sandbox_command(command: list[str], tree: Path, *, network: bool, writable: bool = True,
|
|
86
88
|
source: dict | None = None, auth_home: str = "", provider: str = "", observation_home: str = "") -> tuple[list[str], dict]:
|
|
87
89
|
source = os.environ if source is None else source
|
|
88
|
-
|
|
90
|
+
env = clean_env(source)
|
|
91
|
+
binary = shutil.which(command[0], path=env["PATH"])
|
|
89
92
|
bwrap = shutil.which("bwrap", path=source.get("PATH"))
|
|
90
93
|
if not binary or not bwrap:
|
|
91
94
|
raise RuntimeError("Workspace isolation requires bubblewrap and " + command[0])
|
|
@@ -93,6 +96,7 @@ def sandbox_command(command: list[str], tree: Path, *, network: bool, writable:
|
|
|
93
96
|
raise RuntimeError("Workspace must be a directory")
|
|
94
97
|
tree = tree.resolve()
|
|
95
98
|
CACHE.mkdir(parents=True, exist_ok=True)
|
|
99
|
+
(CACHE / "rtk").mkdir(exist_ok=True)
|
|
96
100
|
# Provider transport uses the same restricted egress, even for read-only tools.
|
|
97
101
|
online = bool(network or provider)
|
|
98
102
|
if online:
|
|
@@ -137,15 +141,24 @@ def sandbox_command(command: list[str], tree: Path, *, network: bool, writable:
|
|
|
137
141
|
or common.is_relative_to(tree) or common.is_relative_to(CACHE.resolve())
|
|
138
142
|
or Path((gitdir / "gitdir").read_text().strip()).resolve() != marker):
|
|
139
143
|
raise RuntimeError("Invalid external worktree Git directory")
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
# Use sandbox-owned parents rather than traversing private host homes.
|
|
145
|
+
# Do not expose repository config (remote URLs/helpers/includes), hooks,
|
|
146
|
+
# other worktrees, or the source checkout. Git remains read-only.
|
|
147
|
+
private_git = Path("/home/agent/.git")
|
|
148
|
+
args += ["--ro-bind", str(marker), str(marker), "--dir", str(private_git)]
|
|
149
|
+
# Combine this worktree's HEAD/index with shared history, without any
|
|
150
|
+
# commondir/gitdir pointers back into the host filesystem.
|
|
151
|
+
for origin, names in (
|
|
152
|
+
(gitdir, ["HEAD", "index", *[p.name for p in gitdir.glob("sharedindex.*")]]),
|
|
153
|
+
(common, ["objects", "refs", "packed-refs", "shallow", *[p.name for p in common.glob("sharedindex.*")]]),
|
|
154
|
+
):
|
|
155
|
+
for name in names:
|
|
156
|
+
if (origin / name).exists():
|
|
157
|
+
args += ["--ro-bind", str(origin / name), str(private_git / name)]
|
|
158
|
+
env.update(GIT_DIR=str(private_git), GIT_COMMON_DIR=str(private_git),
|
|
159
|
+
GIT_WORK_TREE=str(tree))
|
|
146
160
|
elif marker.exists():
|
|
147
161
|
raise RuntimeError("Expected an isolated git worktree")
|
|
148
|
-
env = clean_env(source)
|
|
149
162
|
if provider == "codex":
|
|
150
163
|
auth_path = Path(auth_home) / "auth.json"
|
|
151
164
|
if json.loads(auth_path.read_text()).get('tokens', {}).get('refresh_token') != '':
|