From 68517f1e501c6d9daf48dba6ee0fc1dbf9246178 Mon Sep 17 00:00:00 2001 From: Marco Barisione Date: Fri, 16 Jan 2026 14:14:03 +0000 Subject: [PATCH 1/3] Explain: move `.claude-plugin/` to the top-level directory The most recent version of Claude Code only copies the directory with `.claude-plugin/` in it when installing a plugin, so we ar no longer getting the explain code or the list of dependencies. To solve this, the only option is to move the plugin definition to the top-level, which means we can only have one plugin in the whole repository. --- .claude-plugin/marketplace.json | 2 +- .../.claude-plugin => .claude-plugin}/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename {explain/claude_code_plugin/.claude-plugin => .claude-plugin}/plugin.json (88%) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1355428..14b7295 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ { "name": "undo", "description": "Debug and analyze Undo recordings using AI-powered queries", - "source": "./explain/claude_code_plugin", + "source": "./", "category": "development", "version": "1.0.0", "author": { diff --git a/explain/claude_code_plugin/.claude-plugin/plugin.json b/.claude-plugin/plugin.json similarity index 88% rename from explain/claude_code_plugin/.claude-plugin/plugin.json rename to .claude-plugin/plugin.json index e887532..9a268c8 100644 --- a/explain/claude_code_plugin/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -9,7 +9,7 @@ "homepage": "https://github.com/undoio/addons/tree/master/explain", "mcpServers": { "undo-debugger": { - "command": "${CLAUDE_PLUGIN_ROOT}/run.sh", + "command": "${CLAUDE_PLUGIN_ROOT}/explain/claude_code_plugin/run.sh", "args": [] } }, From 47c672eb936013b67526e4bcee32c93643a25010 Mon Sep 17 00:00:00 2001 From: Marco Barisione Date: Fri, 16 Jan 2026 14:14:04 +0000 Subject: [PATCH 2/3] Explain: make sure the command for `record` is not a wrapper --- explain/claude_code_plugin/controller.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/explain/claude_code_plugin/controller.py b/explain/claude_code_plugin/controller.py index bbb138e..551533a 100644 --- a/explain/claude_code_plugin/controller.py +++ b/explain/claude_code_plugin/controller.py @@ -326,6 +326,10 @@ def record(target_command: list[str], recording: Path, force: bool = False) -> i Args: target_command: The command to execute as a list of arguments (e.g., ["./program", "arg1"]). + The first argument for the command MUST be the actual ELF executable to record, not + a shell wrapper or another command. For instance, `["./my_command", "arg1"]` is + valid, but `["timeout", "5", "./my_command", "arg1"]` or `["/bin/sh", "-c", + "./my_command arg1"]` are not). recording: The path where the UDB recording should be saved. force: If False and the recording file already exists, raises an exception asking the user for confirmation. If True, overwrites the existing file without prompting. From 5807b38999cd42a7d9144f298c2a2cfa2ac57651 Mon Sep 17 00:00:00 2001 From: Marco Barisione Date: Fri, 16 Jan 2026 14:14:05 +0000 Subject: [PATCH 3/3] Explain: fix using different Python versions Dependencies are version-specific, so we can't have a single cache for all of them. This is particularly important with the plugin as users could sometimes use it from inside a virtualenv and sometimes from outside it. --- explain/claude_code_plugin/deps.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/explain/claude_code_plugin/deps.py b/explain/claude_code_plugin/deps.py index b3fb22e..6856f8f 100644 --- a/explain/claude_code_plugin/deps.py +++ b/explain/claude_code_plugin/deps.py @@ -17,7 +17,10 @@ def ensure_sys_paths() -> None: - deps_dir = xdg_dirs.get_plugin_data_dir() / "packages" + # Use per-Python-version package directories so switching Python versions + # doesn't require reinstalling (each version keeps its own cached packages). + py_version = f"{sys.version_info[0]}.{sys.version_info[1]}" + deps_dir = xdg_dirs.get_plugin_data_dir() / f"packages-{py_version}" sys.path.insert(0, str(deps_dir)) _install_deps(deps_dir)