claude-code-tools 1.29.0__tar.gz → 1.29.1__tar.gz
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.
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/PKG-INFO +1 -1
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/__init__.py +1 -1
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_cli_controller.py +2 -5
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_remote_controller.py +166 -49
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/tmux-cli-instructions.md +29 -14
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/pyproject.toml +2 -2
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/.gitignore +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/LICENSE +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/README.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/action_rpc.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/__init__.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/backends.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/config.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/convert.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/discord_bot.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/http_frontend.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/locking.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/mattermost_bot.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/paths.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/readonly.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/registry.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/relay.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/serve.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/store.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/tmux.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/trust.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/turn_log.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/aichat.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/__init__.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/__main__.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/activity.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/cache.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/detect.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/filters.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/model.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/render.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/amux/scan.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/claude_continue.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/cli_passthrough.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_app_server_rpc.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_continue.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_callback.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_fingerprint.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_generation.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_legacy.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_models.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_process.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_reservation.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_resume.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_retry.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_reuse.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_state.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_supervisor.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_wait.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_worker.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/config.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/csv2gsheet.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/delete_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/dotenv_vault.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/env_safe.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_all.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_claude_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_codex_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_claude_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_codex_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_original_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_trimmed_sessions.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/fix_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/gdoc2docx.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/gdoc2md.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/github_wake.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/github_watch_daemon.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/github_watch_store.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/gsheet2csv.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/helper_sessions.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/issue_reply_delivery.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/legacy_session_wrappers.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/md2gdoc.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/move_account.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/__init__.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/hooks.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/migrations.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/models.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/prompt_detect.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/store.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/watcher.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/node_menu_ui.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_claude_noise.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_claude_to_codex.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_codex_flatten.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_codex_to_claude.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_render.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_service.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/resolve_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/resolve_session_names.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/resolve_session_render.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/search_index.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_cli_resolution.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_lineage.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_menu.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_menu_cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_resolution.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_selection.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_utils.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/smart_trim.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/smart_trim_core.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_execution_helpers.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_in_place.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_session.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_session_claude.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_session_codex.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_contract.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_formatting.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_identity_policy.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_manifest.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_projection.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_rendering.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_snapshots.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_store_backends.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_processes.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_runs.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_store_io.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_validation.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/agent-tunnel-spec.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/claude-code-tmux-tutorials.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/dot-zshrc.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/find-claude-session.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/intercom-spec.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/lmsh.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/local-llm-setup.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/docs/vault-documentation.md +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/hatch_build.py +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/node_ui/action_config.js +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/node_ui/menu.js +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/node_ui/package-lock.json +0 -0
- {claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/node_ui/package.json +0 -0
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_cli_controller.py
RENAMED
|
@@ -914,11 +914,8 @@ class CLI:
|
|
|
914
914
|
print(str(e))
|
|
915
915
|
else:
|
|
916
916
|
# Remote mode - kill window
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
print("Window killed")
|
|
920
|
-
except ValueError as e:
|
|
921
|
-
print(str(e))
|
|
917
|
+
self.controller.kill_window(window_id=pane)
|
|
918
|
+
print("Window killed")
|
|
922
919
|
|
|
923
920
|
def wait_idle(self, pane: Optional[str] = None, idle_time: float = 2.0,
|
|
924
921
|
timeout: Optional[int] = None):
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_remote_controller.py
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Remote Tmux Controller
|
|
4
4
|
|
|
5
5
|
Enables tmux-cli to work when run outside of tmux by:
|
|
6
|
-
-
|
|
6
|
+
- Creating a detached tmux session when launching a managed window
|
|
7
7
|
- Managing commands in separate tmux windows (not panes)
|
|
8
8
|
- Providing an API compatible with the local (pane) controller
|
|
9
9
|
"""
|
|
@@ -16,65 +16,141 @@ from typing import Optional, List, Dict, Tuple, Union, Any
|
|
|
16
16
|
|
|
17
17
|
class RemoteTmuxController:
|
|
18
18
|
"""Remote controller that manages a dedicated tmux session and windows."""
|
|
19
|
+
|
|
20
|
+
_ready_option = '@tmux_cli_ready'
|
|
19
21
|
|
|
20
22
|
def __init__(self, session_name: str = "remote-cli-session"):
|
|
21
|
-
"""Initialize with session name
|
|
23
|
+
"""Initialize with a managed session name without creating it."""
|
|
22
24
|
self.session_name = session_name
|
|
23
|
-
self.target_window: Optional[str] = None # e.g., "
|
|
25
|
+
self.target_window: Optional[str] = None # Stable window ID, e.g., "@1"
|
|
24
26
|
print(f"Note: tmux-cli is running outside tmux. Managing windows in session '{session_name}'.")
|
|
25
27
|
print("For better integration, consider running from inside a tmux session.")
|
|
26
28
|
print("Use 'tmux-cli attach' to view the remote session.")
|
|
27
|
-
self._ensure_session()
|
|
28
29
|
|
|
29
30
|
# ----------------------------
|
|
30
31
|
# Internal utilities
|
|
31
32
|
# ----------------------------
|
|
32
|
-
def _run_tmux(self, args: List[str]) -> Tuple[str, int]:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
def _run_tmux(self, args: List[str], include_stderr: bool = False) -> Tuple[str, int]:
|
|
34
|
+
try:
|
|
35
|
+
result = subprocess.run(
|
|
36
|
+
['tmux'] + args,
|
|
37
|
+
capture_output=True,
|
|
38
|
+
text=True
|
|
39
|
+
)
|
|
40
|
+
except OSError as exc:
|
|
41
|
+
raise RuntimeError(f"Could not run tmux {args[0]}: {exc}") from exc
|
|
42
|
+
output = result.stdout.strip()
|
|
43
|
+
if include_stderr and result.returncode != 0:
|
|
44
|
+
output = "\n".join(part for part in (output, result.stderr.strip()) if part)
|
|
45
|
+
return output, result.returncode
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def _session_is_missing(error: str) -> bool:
|
|
49
|
+
"""Recognize tmux's absent-session and absent-server diagnostics only."""
|
|
50
|
+
return (
|
|
51
|
+
"can't find session:" in error
|
|
52
|
+
or error.startswith("no server running on ")
|
|
53
|
+
or (error.startswith("error connecting to ") and "(No such file or directory)" in error)
|
|
37
54
|
)
|
|
38
|
-
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _tmux_failure(action: str, output: str, code: int) -> RuntimeError:
|
|
58
|
+
detail = f": {output}" if output else ""
|
|
59
|
+
return RuntimeError(f"tmux {action} failed (exit {code}){detail}")
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def _window_is_missing(error: str, window_id: str) -> bool:
|
|
63
|
+
"""Only classify a diagnostic for this exact stable ID as a vanished window."""
|
|
64
|
+
return error.strip() in (
|
|
65
|
+
f"no such window: {window_id}",
|
|
66
|
+
f"can't find window: {window_id}",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def _managed_session_exists(self) -> bool:
|
|
70
|
+
output, code = self._run_tmux(['has-session', '-t', f'={self.session_name}'], include_stderr=True)
|
|
71
|
+
if code == 0:
|
|
72
|
+
return True
|
|
73
|
+
if self._session_is_missing(output):
|
|
74
|
+
return False
|
|
75
|
+
raise self._tmux_failure('has-session', output, code)
|
|
39
76
|
|
|
40
77
|
def _ensure_session(self) -> None:
|
|
41
|
-
"""Create the session if
|
|
42
|
-
|
|
43
|
-
if code != 0:
|
|
78
|
+
"""Create the managed session if needed for a new window."""
|
|
79
|
+
if not self._managed_session_exists():
|
|
44
80
|
# Create a detached session using user's default shell
|
|
45
81
|
# Return the session name just to force creation
|
|
46
|
-
self._run_tmux([
|
|
82
|
+
output, code = self._run_tmux([
|
|
47
83
|
'new-session', '-d', '-s', self.session_name, '-P', '-F', '#{session_name}'
|
|
48
|
-
])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if code2 == 0 and win:
|
|
56
|
-
self.target_window = win
|
|
84
|
+
], include_stderr=True)
|
|
85
|
+
if code != 0:
|
|
86
|
+
# Another launcher may have won the check/create race.
|
|
87
|
+
if output != f'duplicate session: {self.session_name}' or not self._managed_session_exists():
|
|
88
|
+
raise self._tmux_failure('new-session', output, code)
|
|
89
|
+
elif not output:
|
|
90
|
+
raise self._tmux_failure('new-session', output, code)
|
|
57
91
|
|
|
58
92
|
def _window_target(self, pane: Optional[str]) -> str:
|
|
59
93
|
"""Resolve user-provided pane/window hint to a tmux target.
|
|
60
94
|
Accepts:
|
|
61
|
-
- None -> use last target window if set else active window in session
|
|
95
|
+
- None -> use last target window if set else a ready active window in session
|
|
62
96
|
- digits (e.g., "1") -> session:index
|
|
63
97
|
- full tmux target (e.g., "name:1" or "name:1.0" or "%12") -> pass-through
|
|
64
98
|
"""
|
|
65
|
-
self._ensure_session()
|
|
66
99
|
if pane is None:
|
|
67
100
|
if self.target_window:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
101
|
+
# Window IDs can be reused after a server restart. Check both
|
|
102
|
+
# membership and readiness before trusting a cached default.
|
|
103
|
+
windows, code = self._run_tmux(
|
|
104
|
+
['list-windows', '-t', f'={self.session_name}',
|
|
105
|
+
'-F', '#{window_id}|#{@tmux_cli_ready}'],
|
|
106
|
+
include_stderr=True,
|
|
107
|
+
)
|
|
108
|
+
if code != 0 and not self._session_is_missing(windows):
|
|
109
|
+
raise self._tmux_failure('list-windows', windows, code)
|
|
110
|
+
expected = f'{self.target_window}|{self.target_window}'
|
|
111
|
+
if code == 0 and expected in windows.splitlines():
|
|
112
|
+
return self.target_window
|
|
113
|
+
self.target_window = None
|
|
114
|
+
if code != 0:
|
|
115
|
+
raise ValueError(
|
|
116
|
+
"No target pane/window specified; managed session "
|
|
117
|
+
f"'{self.session_name}' does not exist. "
|
|
118
|
+
"Launch a window or pass --pane."
|
|
119
|
+
)
|
|
120
|
+
# An existing managed session may have been created by an earlier CLI call.
|
|
121
|
+
win, code = self._run_tmux(
|
|
122
|
+
['display-message', '-p', '-t', f'={self.session_name}:',
|
|
123
|
+
'#{window_id}|#{@tmux_cli_ready}'],
|
|
124
|
+
include_stderr=True,
|
|
125
|
+
)
|
|
126
|
+
if code == 0:
|
|
127
|
+
if not win:
|
|
128
|
+
raise self._tmux_failure('display-message', win, code)
|
|
129
|
+
window_id, separator, ready = win.partition('|')
|
|
130
|
+
if not separator or not window_id.startswith('@'):
|
|
131
|
+
raise self._tmux_failure('display-message', win, code)
|
|
132
|
+
if ready == window_id:
|
|
133
|
+
self.target_window = window_id
|
|
134
|
+
return window_id
|
|
135
|
+
raise ValueError(
|
|
136
|
+
f"No target pane/window specified; managed session '{self.session_name}' "
|
|
137
|
+
"has no successfully launched active window. Launch a window or pass --pane."
|
|
138
|
+
)
|
|
139
|
+
if code != 0 and not (self._session_is_missing(win) or "can't find window:" in win):
|
|
140
|
+
raise self._tmux_failure('display-message', win, code)
|
|
141
|
+
raise ValueError(
|
|
142
|
+
f"No target pane/window specified; managed session '{self.session_name}' "
|
|
143
|
+
"does not exist or has no active window. Launch a window or pass --pane."
|
|
144
|
+
)
|
|
76
145
|
# If user supplied a simple index
|
|
77
|
-
if isinstance(pane,
|
|
146
|
+
if isinstance(pane, bool):
|
|
147
|
+
raise ValueError("Boolean --pane is not a window index")
|
|
148
|
+
if type(pane) is int or (isinstance(pane, str) and pane.isdigit()):
|
|
149
|
+
if not self._managed_session_exists():
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"Managed session '{self.session_name}' does not exist; "
|
|
152
|
+
"launch a window or pass a full --pane target."
|
|
153
|
+
)
|
|
78
154
|
return f"{self.session_name}:{pane}"
|
|
79
155
|
# Otherwise assume user provided a pane/window target or pane id
|
|
80
156
|
return pane
|
|
@@ -92,7 +168,6 @@ class RemoteTmuxController:
|
|
|
92
168
|
Returns a list shaped similarly to local list_panes, with keys:
|
|
93
169
|
id (window target), index, title (window name), active (bool), size (N/A)
|
|
94
170
|
"""
|
|
95
|
-
self._ensure_session()
|
|
96
171
|
out, code = self._run_tmux([
|
|
97
172
|
'list-windows', '-t', self.session_name,
|
|
98
173
|
'-F', '#{window_index}|#{window_name}|#{window_active}|#{window_width}x#{window_height}'
|
|
@@ -117,17 +192,49 @@ class RemoteTmuxController:
|
|
|
117
192
|
"""Launch a command in a new window within the managed session.
|
|
118
193
|
Returns the window target (e.g., "session:1").
|
|
119
194
|
"""
|
|
120
|
-
self.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
args
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
195
|
+
previous_target = self.target_window
|
|
196
|
+
try:
|
|
197
|
+
self._ensure_session()
|
|
198
|
+
args = ['new-window', '-t', f'={self.session_name}:', '-P', '-F',
|
|
199
|
+
'#{session_name}:#{window_index}|#{window_id}']
|
|
200
|
+
if name:
|
|
201
|
+
args.extend(['-n', name])
|
|
202
|
+
if command:
|
|
203
|
+
args.append(command)
|
|
204
|
+
out, code = self._run_tmux(args, include_stderr=True)
|
|
205
|
+
if code != 0 or not out:
|
|
206
|
+
raise self._tmux_failure('new-window', out, code)
|
|
207
|
+
target, separator, window_id = out.partition('|')
|
|
208
|
+
if not separator or not target or not window_id.startswith('@'):
|
|
209
|
+
raise self._tmux_failure('new-window', out, code)
|
|
210
|
+
try:
|
|
211
|
+
marked, mark_code = self._run_tmux(
|
|
212
|
+
['set-option', '-w', '-t', window_id, self._ready_option, window_id],
|
|
213
|
+
include_stderr=True,
|
|
214
|
+
)
|
|
215
|
+
except RuntimeError as exc:
|
|
216
|
+
raise RuntimeError(
|
|
217
|
+
f"Ready mark for created window {window_id} could not be set; "
|
|
218
|
+
f"command may have started. {exc}"
|
|
219
|
+
) from exc
|
|
220
|
+
if mark_code != 0:
|
|
221
|
+
if self._window_is_missing(marked, window_id):
|
|
222
|
+
raise RuntimeError(
|
|
223
|
+
f"Command was launched in window {window_id}, but that window "
|
|
224
|
+
f"disappeared before its ready mark; no live target is available "
|
|
225
|
+
f"(tmux set-option exit {mark_code}: {marked}). "
|
|
226
|
+
"The command may have run; do not retry automatically."
|
|
227
|
+
)
|
|
228
|
+
raise RuntimeError(
|
|
229
|
+
f"{self._tmux_failure('set-option', marked, mark_code)}; "
|
|
230
|
+
f"created window {window_id}; command may have started. "
|
|
231
|
+
"Inspect the window before retrying."
|
|
232
|
+
)
|
|
233
|
+
self.target_window = window_id
|
|
234
|
+
return target
|
|
235
|
+
except Exception:
|
|
236
|
+
self.target_window = previous_target
|
|
237
|
+
raise
|
|
131
238
|
|
|
132
239
|
def send_keys(self, text: str, pane_id: Optional[str] = None, enter: bool = True,
|
|
133
240
|
delay_enter: Union[bool, float] = True, verify_enter: bool = True,
|
|
@@ -272,14 +379,25 @@ class RemoteTmuxController:
|
|
|
272
379
|
|
|
273
380
|
def kill_window(self, window_id: Optional[str] = None):
|
|
274
381
|
target = self._window_target(window_id)
|
|
382
|
+
cached_target = target
|
|
383
|
+
if self.target_window and target != self.target_window:
|
|
384
|
+
resolved, code = self._run_tmux(
|
|
385
|
+
['display-message', '-p', '-t', target, '#{window_id}']
|
|
386
|
+
)
|
|
387
|
+
if code == 0 and resolved:
|
|
388
|
+
cached_target = resolved
|
|
275
389
|
# Ensure the target refers to a window (not a %pane id)
|
|
276
390
|
# If user passed a pane id like %12, tmux can still resolve to its window
|
|
277
391
|
self._run_tmux(['kill-window', '-t', target])
|
|
278
|
-
if self.target_window ==
|
|
392
|
+
if self.target_window == cached_target:
|
|
279
393
|
self.target_window = None
|
|
280
394
|
|
|
281
395
|
def attach_session(self):
|
|
282
|
-
self.
|
|
396
|
+
if not self._managed_session_exists():
|
|
397
|
+
raise ValueError(
|
|
398
|
+
f"Managed session '{self.session_name}' does not exist; "
|
|
399
|
+
"launch a window before attaching."
|
|
400
|
+
)
|
|
283
401
|
# Attach will replace the current terminal view until the user detaches
|
|
284
402
|
subprocess.run(['tmux', 'attach-session', '-t', self.session_name])
|
|
285
403
|
|
|
@@ -289,7 +407,6 @@ class RemoteTmuxController:
|
|
|
289
407
|
|
|
290
408
|
def list_windows(self) -> List[Dict[str, str]]:
|
|
291
409
|
"""List all windows in the managed session with basic info."""
|
|
292
|
-
self._ensure_session()
|
|
293
410
|
out, code = self._run_tmux(['list-windows', '-t', self.session_name, '-F', '#{window_index}|#{window_name}|#{window_active}'])
|
|
294
411
|
if code != 0 or not out:
|
|
295
412
|
return []
|
|
@@ -5,27 +5,40 @@ Automatically detects whether you're inside or outside tmux and uses the appropr
|
|
|
5
5
|
|
|
6
6
|
## Auto-Detection
|
|
7
7
|
- **Inside tmux (Local Mode)**: Manages panes in your current tmux window
|
|
8
|
-
- **Outside tmux (Remote Mode)**:
|
|
8
|
+
- **Outside tmux (Remote Mode)**: Manages windows in a separate tmux session, creating it when `launch` first needs it
|
|
9
|
+
|
|
10
|
+
Remote `status`, `list_panes`, and `list_windows` do not create a session.
|
|
11
|
+
An explicit full pane target (such as `%12` or `myapp:1.2`) works without a
|
|
12
|
+
managed session. Commands without a target require an active window from a
|
|
13
|
+
successful managed `launch`; otherwise, launch a window first or pass `--pane`.
|
|
14
|
+
`attach` requires the managed session to already exist.
|
|
9
15
|
|
|
10
16
|
## Prerequisites
|
|
11
17
|
- tmux must be installed
|
|
12
18
|
- The `tmux-cli` command must be available (installed via `uv tool install`)
|
|
13
19
|
|
|
14
|
-
##
|
|
20
|
+
## Target Identification
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
In local mode, panes can be specified in two simple ways:
|
|
17
23
|
- Just the pane number (e.g., `2`) - refers to pane 2 in the current window
|
|
18
24
|
- Full format: `session:window.pane` (e.g., `myapp:1.2`) - for any pane in any session
|
|
19
25
|
|
|
26
|
+
In remote mode, `launch` returns a window target such as `remote-cli-session:1`.
|
|
27
|
+
Use the returned target as `--pane`. A bare number such as `1` means a managed
|
|
28
|
+
window index, not a pane index; window indices can change if windows move.
|
|
29
|
+
Numeric `--pane=2` examples below show local mode unless labeled as remote.
|
|
30
|
+
|
|
20
31
|
## ⚠️ IMPORTANT: Always Launch a Shell First!
|
|
21
32
|
|
|
22
33
|
**Always launch zsh first** to prevent losing output when commands fail:
|
|
23
34
|
```bash
|
|
24
|
-
tmux-cli launch "zsh" # Do this FIRST
|
|
25
|
-
tmux-cli send "your-command" --pane=
|
|
35
|
+
tmux-cli launch "zsh" # Do this FIRST; remote example returns remote-cli-session:1
|
|
36
|
+
tmux-cli send "your-command" --pane=remote-cli-session:1 # Use the actual returned target
|
|
26
37
|
```
|
|
27
38
|
|
|
28
|
-
If
|
|
39
|
+
If a directly launched command exits before its remote window is marked ready,
|
|
40
|
+
`launch` reports that the command was launched but has no live target. It does
|
|
41
|
+
not retry the command. Launch a shell first to keep output available.
|
|
29
42
|
|
|
30
43
|
## Core Commands
|
|
31
44
|
|
|
@@ -33,7 +46,8 @@ If you launch a command directly and it errors, the pane closes immediately and
|
|
|
33
46
|
```bash
|
|
34
47
|
tmux-cli launch "command"
|
|
35
48
|
# Example: tmux-cli launch "python3"
|
|
36
|
-
#
|
|
49
|
+
# Local return: pane identifier (e.g., myapp:1.2)
|
|
50
|
+
# Remote return: window target (e.g., remote-cli-session:1)
|
|
37
51
|
```
|
|
38
52
|
|
|
39
53
|
### Send input to a pane
|
|
@@ -159,23 +173,23 @@ tmux-cli help
|
|
|
159
173
|
|
|
160
174
|
1. **ALWAYS launch a shell first** (prefer zsh) - this prevents losing output on errors:
|
|
161
175
|
```bash
|
|
162
|
-
tmux-cli launch "zsh" #
|
|
176
|
+
tmux-cli launch "zsh" # Remote: returns a window target - DO THIS FIRST!
|
|
163
177
|
```
|
|
164
178
|
|
|
165
179
|
2. Run your command in the shell:
|
|
166
180
|
```bash
|
|
167
|
-
tmux-cli send "python script.py" --pane=
|
|
181
|
+
tmux-cli send "python script.py" --pane=remote-cli-session:1 # Use the actual returned target
|
|
168
182
|
```
|
|
169
183
|
|
|
170
184
|
3. Interact with the program:
|
|
171
185
|
```bash
|
|
172
|
-
tmux-cli send "user input" --pane=
|
|
173
|
-
tmux-cli capture --pane=
|
|
186
|
+
tmux-cli send "user input" --pane=remote-cli-session:1
|
|
187
|
+
tmux-cli capture --pane=remote-cli-session:1 # Check output
|
|
174
188
|
```
|
|
175
189
|
|
|
176
190
|
4. Clean up when done:
|
|
177
191
|
```bash
|
|
178
|
-
tmux-cli kill --pane=
|
|
192
|
+
tmux-cli kill --pane=remote-cli-session:1
|
|
179
193
|
```
|
|
180
194
|
|
|
181
195
|
## Remote Mode Specific Commands
|
|
@@ -205,7 +219,8 @@ tmux-cli list_windows
|
|
|
205
219
|
- Use `capture` to check the current state before sending input
|
|
206
220
|
- Use `status` to see all available panes and their current state
|
|
207
221
|
- In local mode: Pane identifiers can be session:window.pane format (like `myapp:1.2`) or just pane indices like `1`, `2`
|
|
208
|
-
- In remote mode:
|
|
222
|
+
- In remote mode: Bare numbers like `0`, `1` are window indices; `launch` returns
|
|
223
|
+
a `session:window_index` target, such as `remote-cli-session:1`
|
|
209
224
|
- If you launch a command directly (not via shell), the pane/window closes when
|
|
210
225
|
the command exits
|
|
211
226
|
- **IMPORTANT**: The tool prevents you from killing your own pane/window to avoid
|
|
@@ -222,4 +237,4 @@ tmux-cli wait_idle --pane=2 --idle-time=3.0
|
|
|
222
237
|
|
|
223
238
|
# Now capture the result
|
|
224
239
|
tmux-cli capture --pane=2
|
|
225
|
-
```
|
|
240
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "claude-code-tools"
|
|
3
|
-
version = "1.29.
|
|
3
|
+
version = "1.29.1"
|
|
4
4
|
description = "Collection of tools for working with Claude Code"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -113,7 +113,7 @@ markers = [
|
|
|
113
113
|
|
|
114
114
|
[tool.commitizen]
|
|
115
115
|
name = "cz_conventional_commits"
|
|
116
|
-
version = "1.29.
|
|
116
|
+
version = "1.29.1"
|
|
117
117
|
tag_format = "v$version"
|
|
118
118
|
version_files = [
|
|
119
119
|
"pyproject.toml:version",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/__init__.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/backends.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/config.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/convert.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/discord_bot.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/locking.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/paths.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/readonly.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/registry.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/relay.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/serve.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/session.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/store.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/tmux.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/trust.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/agent_tunnel/turn_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_app_server_rpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_callback.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_fingerprint.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_generation.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_legacy.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_models.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_process.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_reservation.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_resume.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_retry.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_reuse.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_state.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_supervisor.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_wait.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/codex_server_worker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_claude_session.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/export_codex_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_claude_session.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_codex_session.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_original_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/find_trimmed_sessions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/github_watch_daemon.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/github_watch_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/issue_reply_delivery.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/legacy_session_wrappers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/msg/prompt_detect.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_claude_noise.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_claude_to_codex.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_codex_flatten.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/port_codex_to_claude.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/resolve_session_names.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/resolve_session_render.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_cli_resolution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_resolution.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/session_selection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/tmux_execution_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_session_claude.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/trim_session_codex.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_contract.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_formatting.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_manifest.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_projection.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_rendering.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_cli_snapshots.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_processes.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_store_io.py
RENAMED
|
File without changes
|
{claude_code_tools-1.29.0 → claude_code_tools-1.29.1}/claude_code_tools/workflow_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|