cdx-manager 0.5.2 → 0.5.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # CDX Manager
2
2
 
3
- [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.5.2-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
3
+ [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.5.3-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
4
4
 
5
5
  **Run multiple Codex and Claude sessions from one terminal. Switch between accounts instantly.**
6
6
 
@@ -126,7 +126,7 @@ For a specific version:
126
126
 
127
127
  ```bash
128
128
  curl -fsSL https://raw.githubusercontent.com/AlexAgo83/cdx-manager/main/install.sh -o install.sh
129
- CDX_VERSION=v0.5.2 sh install.sh
129
+ CDX_VERSION=v0.5.3 sh install.sh
130
130
  ```
131
131
 
132
132
  From source:
@@ -250,7 +250,7 @@ cdx status
250
250
  | `cdx enable <name> [--json]` | Re-enable a disabled session |
251
251
  | `cdx context show\|path\|init\|edit\|clear\|set [text...] [--json]` | Manage the shared Markdown context for the current workspace |
252
252
  | `cdx handoff <name> [--json]` | Install the current workspace context into a target session and launch it unless `--json` is used |
253
- | `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 |
253
+ | `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 Codex and Claude targets, including cross-provider handoff |
254
254
  | `cdx rmv <name> [--force] [--json]` | Remove a session and its auth data (prompts for confirmation unless `--force`) |
255
255
  | `cdx clean [name] [--json]` | Clear launch transcript logs for one session or all sessions |
256
256
  | `cdx export <file> [--include-auth] [--sessions a,b] [--passphrase-env VAR] [--force] [--json]` | Export sessions to a portable bundle; `--include-auth` encrypts auth data with a passphrase |
@@ -0,0 +1,42 @@
1
+ # Changelog (`0.5.2 -> 0.5.3`)
2
+
3
+ Release date: 2026-05-23
4
+
5
+ ## Major Highlights
6
+
7
+ - Added Claude-compatible handoff launch prompting so Claude targets are told exactly which `shared-context.md` file to read.
8
+ - Added Claude launch transcript capture, enabling transcript-based handoff from Claude source sessions.
9
+ - Enabled cross-provider transcript handoff between Codex and Claude sessions.
10
+ - Prepared the package metadata for the 0.5.3 release across npm, PyPI, CLI version output, and README install examples.
11
+
12
+ ## Claude Handoff
13
+
14
+ - Passes the handoff prompt to Claude as the initial prompt argument during launch.
15
+ - Installs shared context into the target Claude session profile and references the concrete `shared-context.md` path in the prompt.
16
+ - Captures Claude launch transcripts under the session's `claude-home/log/` directory using the same transcript wrapper path as Codex.
17
+ - Preserves Claude `HOME` isolation while running through the transcript wrapper.
18
+
19
+ ## Cross-Provider Handoff
20
+
21
+ - Allows `cdx handoff <source> <target>` when the source and target providers differ.
22
+ - Keeps generated handoff context provider-neutral while still recording source and target provider metadata.
23
+ - Preserves target account authentication and does not copy source credentials.
24
+
25
+ ## Documentation
26
+
27
+ - Updated the command table to document Codex and Claude handoff targets, including cross-provider handoff.
28
+ - Updated the README badge and pinned installer example to `v0.5.3`.
29
+
30
+ ## Validation and Regression Coverage
31
+
32
+ - Added CLI coverage for Claude-to-Claude transcript handoff.
33
+ - Added CLI coverage for Codex-to-Claude handoff.
34
+ - Added CLI coverage proving non-JSON Claude handoff launches Claude with the resume prompt.
35
+ - Updated existing Claude launch coverage to verify transcript-wrapped launches.
36
+
37
+ ## Validation and Regression Evidence
38
+
39
+ - `python3 -m pytest test/test_cli_py.py test/test_runtime_py.py`
40
+ - `python3 -m pytest`
41
+ - `npm run lint`
42
+ - `npm test`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdx-manager",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Terminal session manager for Codex and Claude accounts.",
5
5
  "license": "MIT",
6
6
  "author": "Alexandre Agostini",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cdx-manager"
7
- version = "0.5.2"
7
+ version = "0.5.3"
8
8
  description = "Terminal session manager for Codex and Claude accounts."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
package/src/cli.py CHANGED
@@ -49,7 +49,7 @@ from .status_view import (
49
49
  )
50
50
  from .update_check import check_for_update
51
51
 
52
- VERSION = "0.5.2"
52
+ VERSION = "0.5.3"
53
53
 
54
54
 
55
55
  # ---------------------------------------------------------------------------
@@ -111,9 +111,16 @@ def _build_handoff_context(source, target, transcript_path, transcript, truncate
111
111
  ])
112
112
 
113
113
 
114
- def _handoff_launch_prompt():
114
+ def _handoff_launch_prompt(session, install=None):
115
+ if session.get("provider") == "codex":
116
+ context_ref = "$CODEX_HOME/shared-context.md"
117
+ else:
118
+ context_ref = (install or {}).get("target_path") or os.path.join(
119
+ session.get("authHome") or session.get("sessionRoot") or "~",
120
+ "shared-context.md",
121
+ )
115
122
  return (
116
- "Read $CODEX_HOME/shared-context.md first, then resume the previous session "
123
+ f"Read {context_ref} first, then resume the previous session "
117
124
  "from the latest actionable state. Do not ask me to paste the context again."
118
125
  )
119
126
 
@@ -1017,18 +1024,19 @@ def handle_handoff(rest, ctx):
1017
1024
  if not session:
1018
1025
  raise CdxError(f"Unknown session: {name}")
1019
1026
  install = install_context_for_session(ctx["service"]["base_dir"], session, ctx.get("cwd"))
1027
+ launch_prompt = _handoff_launch_prompt(session, install)
1020
1028
  if json_flag:
1021
1029
  _write_json(ctx, _json_success(
1022
1030
  "handoff",
1023
1031
  f"Installed shared context for {name}",
1024
1032
  context=install,
1025
- launch_prompt=_handoff_launch_prompt(),
1033
+ launch_prompt=launch_prompt,
1026
1034
  session=session,
1027
1035
  ))
1028
1036
  return 0
1029
1037
  text = f"Shared context installed for {name}: {install['target_path']}"
1030
1038
  ctx["out"](f"{_info(text, ctx['use_color'])}\n")
1031
- return handle_launch(name, ctx, initial_prompt=_handoff_launch_prompt())
1039
+ return handle_launch(name, ctx, initial_prompt=launch_prompt)
1032
1040
 
1033
1041
  source_name, target_name = args
1034
1042
  if source_name == target_name:
@@ -1039,8 +1047,6 @@ def handle_handoff(rest, ctx):
1039
1047
  target = ctx["service"]["get_session"](target_name)
1040
1048
  if not target:
1041
1049
  raise CdxError(f"Unknown session: {target_name}")
1042
- if source["provider"] != target["provider"]:
1043
- raise CdxError("Source and target sessions must use the same provider for handoff.")
1044
1050
  transcript_path = _latest_launch_transcript_path(source)
1045
1051
  if not transcript_path:
1046
1052
  raise CdxError(f"No launch transcript found for session: {source_name}")
@@ -1048,6 +1054,7 @@ def handle_handoff(rest, ctx):
1048
1054
  context = _build_handoff_context(source, target, transcript_path, transcript, truncated=truncated)
1049
1055
  write_result = write_context(ctx["service"]["base_dir"], context, ctx.get("cwd"))
1050
1056
  install = install_context_for_session(ctx["service"]["base_dir"], target, ctx.get("cwd"))
1057
+ launch_prompt = _handoff_launch_prompt(target, install)
1051
1058
  if json_flag:
1052
1059
  _write_json(ctx, _json_success(
1053
1060
  "handoff",
@@ -1057,9 +1064,9 @@ def handle_handoff(rest, ctx):
1057
1064
  target_session=target,
1058
1065
  source_transcript=transcript_path,
1059
1066
  shared_context=write_result,
1060
- launch_prompt=_handoff_launch_prompt(),
1067
+ launch_prompt=launch_prompt,
1061
1068
  ))
1062
1069
  return 0
1063
1070
  text = f"Handoff prepared from {source_name} to {target_name}: {install['target_path']}"
1064
1071
  ctx["out"](f"{_info(text, ctx['use_color'])}\n")
1065
- return handle_launch(target_name, ctx, initial_prompt=_handoff_launch_prompt())
1072
+ return handle_launch(target_name, ctx, initial_prompt=launch_prompt)
@@ -103,15 +103,18 @@ def _build_launch_spec(session, cwd=None, env_override=None, initial_prompt=None
103
103
  env_override = env_override or {}
104
104
  env = {**os.environ, **env_override}
105
105
  if session["provider"] == "claude":
106
- return {
106
+ args = ["--name", session["name"]]
107
+ if initial_prompt:
108
+ args.append(initial_prompt)
109
+ return _wrap_launch_with_transcript(session, {
107
110
  "command": "claude",
108
- "args": ["--name", session["name"]],
111
+ "args": args,
109
112
  "options": {
110
113
  "cwd": cwd,
111
114
  "env": {**env, **_home_env_overrides(_get_auth_home(session))},
112
115
  },
113
116
  "label": "claude",
114
- }
117
+ }, env=env)
115
118
  args = ["--no-alt-screen", "--cd", cwd]
116
119
  if initial_prompt:
117
120
  args.append(initial_prompt)