cdx-manager 0.26.4 → 0.26.6

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
@@ -4,7 +4,7 @@
4
4
 
5
5
  <br clear="left"/>
6
6
 
7
- [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.26.4-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
7
+ [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.26.6-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
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.26.4
1
+ 0.26.6
@@ -0,0 +1,17 @@
1
+ # CDX Manager 0.26.5
2
+
3
+ Release date: 2026-11-06
4
+
5
+ ## Fixes
6
+
7
+ - Skip Claude `isMeta` user records in conversation views (#114,
8
+ `03de3770d257cc9643e542d1dbd3120e9ae71ff4`). Hide harness notes such as
9
+ image size hints and caveats, and classify oversized tool results as tool
10
+ entries so they no longer appear as operator messages.
11
+
12
+ ## Maintenance
13
+
14
+ - Record tray companion checksums for v0.26.4
15
+ (`4b42be1314c4b575369858d05e3e932687e5c8df`).
16
+ - Record release archive checksums for v0.26.4
17
+ (`67014979a69c853aa4d27c89577ce022760f6514`).
@@ -0,0 +1,17 @@
1
+ # CDX Manager 0.26.6
2
+
3
+ Release date: 2026-11-06
4
+
5
+ ## Fixes
6
+
7
+ - Unwrap matching Claude `pasted_content` tags in conversation views so pasted
8
+ text appears without its wrapper (#116,
9
+ `84cb0de57407e4568b8d9918787a8d370ec76d10`). Preserve literal text with
10
+ unmatched tags.
11
+
12
+ ## Maintenance
13
+
14
+ - Record tray companion checksums for v0.26.5
15
+ (`0bd3af61dbb1c848c9a14cbd10ce4b6af439b3c9`).
16
+ - Record release archive checksums for v0.26.5
17
+ (`19d2d3c7443dc5573afce982086fd0d38d89fad2`).
@@ -837,6 +837,28 @@
837
837
  "x86_64-pc-windows-msvc": "7b9d9fc24dd5d4285a5cac7e746614654deaebe197ab38fa6e1c302da34e0358",
838
838
  "x86_64-unknown-linux-musl": "51ea6902917697f5d16ef994bb01d0d0c6293b60c8f26b3735cb08925b3af616"
839
839
  }
840
+ },
841
+ "v0.26.4": {
842
+ "github_tarball_sha256": "a691b54a120807f7b56ec36aca35fa5efd95f75f589dda4d8fdece51c5a32ccf",
843
+ "github_zip_sha256": "53247a7f57d0429d10c12326d5aa46862a97d8dc93835744a0ff88ddf898667b",
844
+ "tray_assets": {
845
+ "aarch64-apple-darwin": "4fbf37673acaf84b053d2f8607162690155a625406d82b77a9dbf388ac77a102",
846
+ "aarch64-unknown-linux-musl": "85041278763597ca90fa25791e82b6db53b96e31a9f2aa421160d8c113e6a381",
847
+ "x86_64-apple-darwin": "0a4c1f503a7da6c8aa13e8d30d836f5d1cc44c1ac1e24534279801e6eeb3d661",
848
+ "x86_64-pc-windows-msvc": "40e0a2e7d72cacbf2fa5fc241484e901228e44214f053c1c1defede62045624b",
849
+ "x86_64-unknown-linux-musl": "f24dea41496fa347b64873066b6b57fbbca6480c4bef1769a3bcd47e3dcb6b34"
850
+ }
851
+ },
852
+ "v0.26.5": {
853
+ "github_tarball_sha256": "45bae3e2dccc49ac47c4c0c3fa57053b391ce3ddf8c56f002f10b56a989d4c1b",
854
+ "github_zip_sha256": "3bdfc7c87beb1a3903e979ec5680d7b18f089cd0ff11728ae895faac472b2759",
855
+ "tray_assets": {
856
+ "aarch64-apple-darwin": "df17b304e0442f5a2f71d18ed754a98d0151b48708117f47a6cb8106055a77b3",
857
+ "aarch64-unknown-linux-musl": "792948a0c48f8221fbf87b6c77e5d4c9e29aac0cf0738857a5ae3346794b5c01",
858
+ "x86_64-apple-darwin": "18923fe1f9bda34ef52b972002845aa914a404beff0de9963f6f9fb0a4c2f0b1",
859
+ "x86_64-pc-windows-msvc": "1ea355b54e05ea6d78a3a23757a9ad5dd2228aa1d939fb7992082e16da579abb",
860
+ "x86_64-unknown-linux-musl": "770fabb26784efb607d2cce6d6bee51c3d7121283c55cf4cacb9b54ac75e4450"
861
+ }
840
862
  }
841
863
  }
842
864
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdx-manager",
3
- "version": "0.26.4",
3
+ "version": "0.26.6",
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.26.4"
7
+ version = "0.26.6"
8
8
  description = "Terminal session manager for Codex and Claude accounts."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9.2"
@@ -66,6 +66,8 @@ _CLAUDE_HARNESS = re.compile(
66
66
  r"\s*(?:<(?P<tag>task-notification|local-command-stdout|local-command-stderr|command-name|command-message|command-args|system-reminder)>"
67
67
  r"(?:(?!</(?P=tag)>).)*</(?P=tag)>\s*)+", re.S,
68
68
  )
69
+ # Claude Code wraps long pasted text in matching tags; show only the pasted text.
70
+ _CLAUDE_PASTED = re.compile(r'<pasted_content id="([0-9A-Za-z]{1,32})">\n?(.*?)\n?</pasted_content id="\1">', re.S)
69
71
  _CLAUDE_MID_TURN_START = "The user sent a new message while you were working:\n"
70
72
  _CLAUDE_MID_TURN_END = re.compile(
71
73
  r"\n+This is how Claude Code surfaces messages the user sends mid-turn[^\n]*"
@@ -81,6 +83,8 @@ def _claude_user_content(content):
81
83
  blocks = [dict(block) if isinstance(block, dict) else block for block in blocks]
82
84
  texts = [block for block in blocks if isinstance(block, dict)
83
85
  and block.get("type") == "text" and isinstance(block.get("text"), str)]
86
+ for block in texts:
87
+ block["text"] = _CLAUDE_PASTED.sub(r"\2", block["text"])
84
88
  # Require both anchored boundaries; a quoted sentence alone is user content.
85
89
  if texts and texts[0]["text"].startswith(_CLAUDE_MID_TURN_START):
86
90
  end = _CLAUDE_MID_TURN_END.search(texts[-1]["text"])
@@ -99,6 +103,9 @@ def _entries(provider, record, names):
99
103
  return []
100
104
  if not _conversation_record(provider, record.get("type")):
101
105
  return []
106
+ # Claude Code marks its own user-role notes (image size hints, caveats) as isMeta.
107
+ if provider == "claude" and record.get("isMeta"):
108
+ return []
102
109
  stamp = record.get("timestamp")
103
110
  try:
104
111
  datetime.fromisoformat(stamp.replace("Z", "+00:00"))
@@ -214,6 +221,11 @@ def _oversized_entry(provider, prefix):
214
221
  value, _ = json.JSONDecoder().raw_decode(prefix, role) if role is not None else (None, 0)
215
222
  except (ValueError, RecursionError):
216
223
  value = None
224
+ if provider == "claude" and value == "user":
225
+ # A large tool result (an image read) is tool output, never an operator message.
226
+ content = _field_start(prefix, "content", message)
227
+ if content is not None and '"tool_result"' in prefix[content:content + 300]:
228
+ return _entry("tool", name="tool", summary="Result recorded")
217
229
  return _entry(value if value in ("user", "assistant", "tool") else "tool",
218
230
  "[élément trop volumineux ignoré]")
219
231