claude-code-tools 1.17.0__tar.gz → 1.19.0__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.
Files changed (137) hide show
  1. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/PKG-INFO +42 -79
  2. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/README.md +25 -78
  3. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/__init__.py +1 -1
  4. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/aichat.py +111 -4
  5. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server.py +32 -31
  6. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_fingerprint.py +205 -15
  7. claude_code_tools-1.19.0/claude_code_tools/codex_server_legacy.py +278 -0
  8. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_models.py +10 -32
  9. claude_code_tools-1.19.0/claude_code_tools/codex_server_reservation.py +70 -0
  10. claude_code_tools-1.19.0/claude_code_tools/codex_server_retry.py +45 -0
  11. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_reuse.py +21 -0
  12. claude_code_tools-1.19.0/claude_code_tools/codex_server_state.py +65 -0
  13. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/export_session.py +249 -140
  14. claude_code_tools-1.19.0/claude_code_tools/port_claude_noise.py +405 -0
  15. claude_code_tools-1.19.0/claude_code_tools/port_claude_to_codex.py +760 -0
  16. claude_code_tools-1.19.0/claude_code_tools/port_codex_flatten.py +518 -0
  17. claude_code_tools-1.19.0/claude_code_tools/port_codex_to_claude.py +714 -0
  18. claude_code_tools-1.19.0/claude_code_tools/port_service.py +384 -0
  19. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/resolve_session.py +380 -217
  20. claude_code_tools-1.19.0/claude_code_tools/resolve_session_names.py +60 -0
  21. claude_code_tools-1.19.0/claude_code_tools/resolve_session_render.py +177 -0
  22. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/session_utils.py +281 -105
  23. claude_code_tools-1.19.0/claude_code_tools/voice_type/__init__.py +6 -0
  24. claude_code_tools-1.19.0/claude_code_tools/voice_type/app.py +625 -0
  25. claude_code_tools-1.19.0/claude_code_tools/voice_type/cli.py +231 -0
  26. claude_code_tools-1.19.0/claude_code_tools/voice_type/config.py +400 -0
  27. claude_code_tools-1.19.0/claude_code_tools/voice_type/engine_parakeet.py +999 -0
  28. claude_code_tools-1.19.0/claude_code_tools/voice_type/engine_parakeet_mlx.py +196 -0
  29. claude_code_tools-1.19.0/claude_code_tools/voice_type/engines.py +183 -0
  30. claude_code_tools-1.19.0/claude_code_tools/voice_type/hotkey.py +361 -0
  31. claude_code_tools-1.19.0/claude_code_tools/voice_type/inject.py +69 -0
  32. claude_code_tools-1.19.0/claude_code_tools/voice_type/logic.py +119 -0
  33. claude_code_tools-1.19.0/claude_code_tools/voice_type/overlay.py +235 -0
  34. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/pyproject.toml +27 -2
  35. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/.gitignore +0 -0
  36. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/LICENSE +0 -0
  37. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/action_rpc.py +0 -0
  38. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/__init__.py +0 -0
  39. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/backends.py +0 -0
  40. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/cli.py +0 -0
  41. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/config.py +0 -0
  42. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/convert.py +0 -0
  43. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/discord_bot.py +0 -0
  44. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/locking.py +0 -0
  45. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/paths.py +0 -0
  46. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/registry.py +0 -0
  47. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/session.py +0 -0
  48. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/store.py +0 -0
  49. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/tmux.py +0 -0
  50. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/agent_tunnel/trust.py +0 -0
  51. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/claude_continue.py +0 -0
  52. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_continue.py +0 -0
  53. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_cli.py +0 -0
  54. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_generation.py +0 -0
  55. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_process.py +0 -0
  56. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_supervisor.py +0 -0
  57. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/codex_server_worker.py +0 -0
  58. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/config.py +0 -0
  59. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/csv2gsheet.py +0 -0
  60. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/delete_session.py +0 -0
  61. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/dotenv_vault.py +0 -0
  62. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/env_safe.py +0 -0
  63. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/export_all.py +0 -0
  64. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/export_claude_session.py +0 -0
  65. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/export_codex_session.py +0 -0
  66. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/find_claude_session.py +0 -0
  67. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/find_codex_session.py +0 -0
  68. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/find_original_session.py +0 -0
  69. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/find_session.py +0 -0
  70. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/find_trimmed_sessions.py +0 -0
  71. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/fix_session.py +0 -0
  72. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/gdoc2docx.py +0 -0
  73. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/gdoc2md.py +0 -0
  74. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/gsheet2csv.py +0 -0
  75. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/md2gdoc.py +0 -0
  76. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/__init__.py +0 -0
  77. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/cli.py +0 -0
  78. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/hooks.py +0 -0
  79. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/models.py +0 -0
  80. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/prompt_detect.py +0 -0
  81. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/store.py +0 -0
  82. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/msg/watcher.py +0 -0
  83. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/node_menu_ui.py +0 -0
  84. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/search_index.py +0 -0
  85. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/session_lineage.py +0 -0
  86. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/session_menu.py +0 -0
  87. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/session_menu_cli.py +0 -0
  88. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/smart_trim.py +0 -0
  89. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/smart_trim_core.py +0 -0
  90. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/tmux_cli_controller.py +0 -0
  91. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/tmux_execution_helpers.py +0 -0
  92. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/tmux_remote_controller.py +0 -0
  93. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/trim_in_place.py +0 -0
  94. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/trim_session.py +0 -0
  95. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/trim_session_claude.py +0 -0
  96. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/trim_session_codex.py +0 -0
  97. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli.py +0 -0
  98. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_contract.py +0 -0
  99. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_formatting.py +0 -0
  100. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_identity_policy.py +0 -0
  101. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_manifest.py +0 -0
  102. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_projection.py +0 -0
  103. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_rendering.py +0 -0
  104. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_snapshots.py +0 -0
  105. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_cli_store_backends.py +0 -0
  106. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_processes.py +0 -0
  107. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_runs.py +0 -0
  108. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_store_io.py +0 -0
  109. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/claude_code_tools/workflow_validation.py +0 -0
  110. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/agent-tunnel-spec.md +0 -0
  111. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/ai-agent-writing-skills.md +0 -0
  112. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/cc-codex-instructions.md +0 -0
  113. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/claude-code-chutes.md +0 -0
  114. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/claude-code-tmux-tutorials.md +0 -0
  115. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/dot-zshrc.md +0 -0
  116. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/ensemble-ideas.md +0 -0
  117. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/example-with-images.md +0 -0
  118. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/find-claude-session.md +0 -0
  119. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/intercom-spec.md +0 -0
  120. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/linked-in-20260102.md +0 -0
  121. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/lmsh.md +0 -0
  122. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/local-llm-setup.md +0 -0
  123. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/msg-phase-a-plan.md +0 -0
  124. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/msg-plan-v2.md +0 -0
  125. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/paper-writing-style-transfer-tools.md +0 -0
  126. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/reddit-aichat-resume-v2.md +0 -0
  127. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/reddit-aichat-resume.md +0 -0
  128. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/reddit-aichat.md +0 -0
  129. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/reddit-post.md +0 -0
  130. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/rollover-details.md +0 -0
  131. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/tmux-cli-instructions.md +0 -0
  132. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/docs/vault-documentation.md +0 -0
  133. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/hatch_build.py +0 -0
  134. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/node_ui/action_config.js +0 -0
  135. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/node_ui/menu.js +0 -0
  136. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/node_ui/package-lock.json +0 -0
  137. {claude_code_tools-1.17.0 → claude_code_tools-1.19.0}/node_ui/package.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-tools
3
- Version: 1.17.0
3
+ Version: 1.19.0
4
4
  Summary: Collection of tools for working with Claude Code
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -22,6 +22,22 @@ Provides-Extra: gdocs
22
22
  Requires-Dist: google-api-python-client>=2.0.0; extra == 'gdocs'
23
23
  Requires-Dist: google-auth-oauthlib>=1.0.0; extra == 'gdocs'
24
24
  Requires-Dist: pillow>=10.0.0; extra == 'gdocs'
25
+ Provides-Extra: voice
26
+ Requires-Dist: moonshine-voice>=0.0.69; extra == 'voice'
27
+ Requires-Dist: pynput>=1.7.7; extra == 'voice'
28
+ Provides-Extra: voice-mlx
29
+ Requires-Dist: numpy>=1.26.0; extra == 'voice-mlx'
30
+ Requires-Dist: parakeet-mlx>=0.5.0; extra == 'voice-mlx'
31
+ Requires-Dist: pynput>=1.7.7; extra == 'voice-mlx'
32
+ Requires-Dist: sherpa-onnx-core<1.13,>=1.12.0; extra == 'voice-mlx'
33
+ Requires-Dist: sherpa-onnx<1.13,>=1.12.0; extra == 'voice-mlx'
34
+ Requires-Dist: sounddevice>=0.5.0; extra == 'voice-mlx'
35
+ Provides-Extra: voice-parakeet
36
+ Requires-Dist: numpy>=1.26.0; extra == 'voice-parakeet'
37
+ Requires-Dist: pynput>=1.7.7; extra == 'voice-parakeet'
38
+ Requires-Dist: sherpa-onnx-core<1.13,>=1.12.0; extra == 'voice-parakeet'
39
+ Requires-Dist: sherpa-onnx<1.13,>=1.12.0; extra == 'voice-parakeet'
40
+ Requires-Dist: sounddevice>=0.5.0; extra == 'voice-parakeet'
25
41
  Description-Content-Type: text/markdown
26
42
 
27
43
  <div align="center">
@@ -66,81 +82,14 @@ separate Rust binary:
66
82
  [Releases](https://github.com/pchalasani/claude-code-tools/releases)
67
83
  (look for `rust-v*`)
68
84
 
69
- Install the Claude Code workflow plugin:
85
+ Install the Claude Code
86
+ [plugins](https://pchalasani.github.io/claude-code-tools/getting-started/plugins/)
87
+ for hooks, skills, and agents:
70
88
 
71
89
  ```bash
72
90
  claude plugin marketplace add pchalasani/claude-code-tools
73
- claude plugin install workflow@cctools-plugins
74
91
  ```
75
92
 
76
- Install the equivalent dynamic workflow plugin for Codex:
77
-
78
- ```bash
79
- codex plugin marketplace add pchalasani/claude-code-tools
80
- codex plugin add dynamic-workflow@cctools-codex-plugins
81
- ```
82
-
83
- The Codex plugin installs independently: it does not require the Python
84
- `claude-code-tools` package or an npm install. Node.js 20 or newer and Codex
85
- CLI 0.136.0 or newer are required for callbacks. Version 0.136.0 is the first
86
- compatible CLI release for this callback protocol. Codex still marks the app
87
- server and remote TUI interfaces as experimental, so those surfaces may evolve.
88
- The plugin can notify the originating Codex thread through Codex's shared app
89
- server after a detached workflow finishes. Callback preflight also rejects a
90
- stale connected server.
91
-
92
- The optional Python package makes that callback setup a single command:
93
-
94
- ```bash
95
- codex-dynamic
96
- # Or continue the latest conversation:
97
- codex-dynamic resume --last
98
- ```
99
-
100
- `codex-dynamic` starts or reuses the local app server and then hands the
101
- terminal directly to Codex. After a plugin or Codex upgrade, the next launch
102
- automatically starts a fresh server generation; existing sessions and workflow
103
- callbacks stay connected to their old generation. No manual restart is needed.
104
- Use `codex-server status` or `logs` for nondisruptive inspection. A forced stop
105
- or restart cleans up every retained generation and disconnects its attached
106
- TUIs, so use those commands only after exiting the sessions normally.
107
-
108
- The Python package also installs `codex-workflows`, an observational dashboard
109
- for durable workflow runs:
110
-
111
- ```bash
112
- codex-workflows
113
- codex-workflows watch --limit 20
114
- codex-workflows show RUN_ID
115
- codex-workflows --all
116
- ```
117
-
118
- The default list contains only active workflows and identifies the project
119
- folder from which each workflow was launched. Use `show RUN_ID` for its full
120
- working directory, or `--all` to include completed and diagnostic history. The
121
- command reads durable workflow state and process metadata. It never changes a
122
- run, sends a signal, repairs state, or launches an agent. See the
123
- [codex-workflows reference][codex-workflows-reference] for filters, JSON output,
124
- and the complete versioned schema.
125
-
126
- [codex-workflows-reference]:
127
- //pchalasani.github.io/claude-code-tools/tools/codex-dynamic/#observe-workflow-runs
128
-
129
- Server management and passive supervision add no model calls. Completion
130
- reporting starts a new turn only while the thread is idle; otherwise it steers
131
- and extends the active turn. Either reporting path consumes model tokens.
132
-
133
- Each workflow `run` or `resume` uses narrow host execution for that exact
134
- reviewed supervisor command. The workflow JavaScript remains restricted, and
135
- every headless Codex worker keeps its declared sandbox.
136
-
137
- See the
138
- [Claude → Codex migration guide][claude-to-codex-guide]
139
- for usage and workflow-porting instructions.
140
-
141
- [claude-to-codex-guide]:
142
- https://pchalasani.github.io/claude-code-tools/guides/claude-to-codex/
143
-
144
93
  ---
145
94
 
146
95
  Click a card to jump to that feature, or
@@ -171,17 +120,22 @@ Click a card to jump to that feature, or
171
120
  </a>
172
121
  </td>
173
122
  <td align="center">
123
+ <a href="https://pchalasani.github.io/claude-code-tools/tools/voice-type/">
124
+ <img src="assets/card-voice-type.svg" alt="voice-type" width="200"/>
125
+ </a>
126
+ </td>
127
+ <td align="center">
174
128
  <a href="https://pchalasani.github.io/claude-code-tools/tools/tmux-cli/">
175
129
  <img src="assets/card-tmux.svg" alt="tmux-cli" width="200"/>
176
130
  </a>
177
131
  </td>
132
+ </tr>
133
+ <tr>
178
134
  <td align="center">
179
135
  <a href="https://pchalasani.github.io/claude-code-tools/tools/agent-tunnel/">
180
136
  <img src="assets/card-agent-tunnel.svg" alt="agent-tunnel" width="200"/>
181
137
  </a>
182
138
  </td>
183
- </tr>
184
- <tr>
185
139
  <td align="center">
186
140
  <a href="https://pchalasani.github.io/claude-code-tools/tools/lmsh/">
187
141
  <img src="assets/card-lmsh.svg" alt="lmsh" width="200"/>
@@ -192,13 +146,13 @@ Click a card to jump to that feature, or
192
146
  <img src="assets/card-vault.svg" alt="vault" width="200"/>
193
147
  </a>
194
148
  </td>
149
+ </tr>
150
+ <tr>
195
151
  <td align="center">
196
152
  <a href="https://pchalasani.github.io/claude-code-tools/tools/env-safe/">
197
153
  <img src="assets/card-env-safe.svg" alt="env-safe" width="200"/>
198
154
  </a>
199
155
  </td>
200
- </tr>
201
- <tr>
202
156
  <td align="center">
203
157
  <a href="https://pchalasani.github.io/claude-code-tools/plugins-detail/safety-hooks/">
204
158
  <img src="assets/card-safety.svg" alt="safety" width="200"/>
@@ -209,13 +163,13 @@ Click a card to jump to that feature, or
209
163
  <img src="assets/card-statusline.svg" alt="statusline" width="200"/>
210
164
  </a>
211
165
  </td>
166
+ </tr>
167
+ <tr>
212
168
  <td align="center">
213
169
  <a href="https://pchalasani.github.io/claude-code-tools/integrations/google-docs/">
214
170
  <img src="assets/card-gdocs.svg" alt="gdocs" width="200"/>
215
171
  </a>
216
172
  </td>
217
- </tr>
218
- <tr>
219
173
  <td align="center">
220
174
  <a href="https://pchalasani.github.io/claude-code-tools/integrations/google-sheets/">
221
175
  <img src="assets/card-gsheets.svg" alt="gsheets" width="200"/>
@@ -226,13 +180,13 @@ Click a card to jump to that feature, or
226
180
  <img src="assets/card-alt.svg" alt="alt" width="200"/>
227
181
  </a>
228
182
  </td>
183
+ </tr>
184
+ <tr>
229
185
  <td align="center">
230
186
  <a href="https://pchalasani.github.io/claude-code-tools/plugins-detail/voice/">
231
187
  <img src="assets/card-voice.svg" alt="voice" width="200"/>
232
188
  </a>
233
189
  </td>
234
- </tr>
235
- <tr>
236
190
  <td align="center">
237
191
  <a href="https://pchalasani.github.io/claude-code-tools/tools/fix-session/">
238
192
  <img src="assets/card-session-repair.svg" alt="session repair" width="200"/>
@@ -243,6 +197,8 @@ Click a card to jump to that feature, or
243
197
  <img src="assets/card-sasy-guard.svg" alt="sasy-guard" width="200"/>
244
198
  </a>
245
199
  </td>
200
+ </tr>
201
+ <tr>
246
202
  <td align="center">
247
203
  <a href="https://pchalasani.github.io/claude-code-tools/guides/claude-to-codex/">
248
204
  <img src="assets/card-claude-to-codex.svg" alt="Claude to Codex" width="200"/>
@@ -287,6 +243,13 @@ See [tmux-cli](https://pchalasani.github.io/claude-code-tools/tools/tmux-cli/) i
287
243
  ## Voice Plugin
288
244
  See [Voice](https://pchalasani.github.io/claude-code-tools/plugins-detail/voice/) in the full documentation.
289
245
 
246
+ <a id="voice-type"></a>
247
+ ## voice-type — Local Voice Dictation
248
+ Fully on-device speech-to-text (Moonshine + VAD) that types wherever your
249
+ cursor is, with a configurable toggle hotkey and optional wake word.
250
+ Install with `uv tool install "claude-code-tools[voice]"`.
251
+ See [voice-type](https://pchalasani.github.io/claude-code-tools/tools/voice-type/) in the full documentation.
252
+
290
253
  <a id="license"></a>
291
254
  ## License
292
255
 
@@ -40,81 +40,14 @@ separate Rust binary:
40
40
  [Releases](https://github.com/pchalasani/claude-code-tools/releases)
41
41
  (look for `rust-v*`)
42
42
 
43
- Install the Claude Code workflow plugin:
43
+ Install the Claude Code
44
+ [plugins](https://pchalasani.github.io/claude-code-tools/getting-started/plugins/)
45
+ for hooks, skills, and agents:
44
46
 
45
47
  ```bash
46
48
  claude plugin marketplace add pchalasani/claude-code-tools
47
- claude plugin install workflow@cctools-plugins
48
49
  ```
49
50
 
50
- Install the equivalent dynamic workflow plugin for Codex:
51
-
52
- ```bash
53
- codex plugin marketplace add pchalasani/claude-code-tools
54
- codex plugin add dynamic-workflow@cctools-codex-plugins
55
- ```
56
-
57
- The Codex plugin installs independently: it does not require the Python
58
- `claude-code-tools` package or an npm install. Node.js 20 or newer and Codex
59
- CLI 0.136.0 or newer are required for callbacks. Version 0.136.0 is the first
60
- compatible CLI release for this callback protocol. Codex still marks the app
61
- server and remote TUI interfaces as experimental, so those surfaces may evolve.
62
- The plugin can notify the originating Codex thread through Codex's shared app
63
- server after a detached workflow finishes. Callback preflight also rejects a
64
- stale connected server.
65
-
66
- The optional Python package makes that callback setup a single command:
67
-
68
- ```bash
69
- codex-dynamic
70
- # Or continue the latest conversation:
71
- codex-dynamic resume --last
72
- ```
73
-
74
- `codex-dynamic` starts or reuses the local app server and then hands the
75
- terminal directly to Codex. After a plugin or Codex upgrade, the next launch
76
- automatically starts a fresh server generation; existing sessions and workflow
77
- callbacks stay connected to their old generation. No manual restart is needed.
78
- Use `codex-server status` or `logs` for nondisruptive inspection. A forced stop
79
- or restart cleans up every retained generation and disconnects its attached
80
- TUIs, so use those commands only after exiting the sessions normally.
81
-
82
- The Python package also installs `codex-workflows`, an observational dashboard
83
- for durable workflow runs:
84
-
85
- ```bash
86
- codex-workflows
87
- codex-workflows watch --limit 20
88
- codex-workflows show RUN_ID
89
- codex-workflows --all
90
- ```
91
-
92
- The default list contains only active workflows and identifies the project
93
- folder from which each workflow was launched. Use `show RUN_ID` for its full
94
- working directory, or `--all` to include completed and diagnostic history. The
95
- command reads durable workflow state and process metadata. It never changes a
96
- run, sends a signal, repairs state, or launches an agent. See the
97
- [codex-workflows reference][codex-workflows-reference] for filters, JSON output,
98
- and the complete versioned schema.
99
-
100
- [codex-workflows-reference]:
101
- //pchalasani.github.io/claude-code-tools/tools/codex-dynamic/#observe-workflow-runs
102
-
103
- Server management and passive supervision add no model calls. Completion
104
- reporting starts a new turn only while the thread is idle; otherwise it steers
105
- and extends the active turn. Either reporting path consumes model tokens.
106
-
107
- Each workflow `run` or `resume` uses narrow host execution for that exact
108
- reviewed supervisor command. The workflow JavaScript remains restricted, and
109
- every headless Codex worker keeps its declared sandbox.
110
-
111
- See the
112
- [Claude → Codex migration guide][claude-to-codex-guide]
113
- for usage and workflow-porting instructions.
114
-
115
- [claude-to-codex-guide]:
116
- https://pchalasani.github.io/claude-code-tools/guides/claude-to-codex/
117
-
118
51
  ---
119
52
 
120
53
  Click a card to jump to that feature, or
@@ -145,17 +78,22 @@ Click a card to jump to that feature, or
145
78
  </a>
146
79
  </td>
147
80
  <td align="center">
81
+ <a href="https://pchalasani.github.io/claude-code-tools/tools/voice-type/">
82
+ <img src="assets/card-voice-type.svg" alt="voice-type" width="200"/>
83
+ </a>
84
+ </td>
85
+ <td align="center">
148
86
  <a href="https://pchalasani.github.io/claude-code-tools/tools/tmux-cli/">
149
87
  <img src="assets/card-tmux.svg" alt="tmux-cli" width="200"/>
150
88
  </a>
151
89
  </td>
90
+ </tr>
91
+ <tr>
152
92
  <td align="center">
153
93
  <a href="https://pchalasani.github.io/claude-code-tools/tools/agent-tunnel/">
154
94
  <img src="assets/card-agent-tunnel.svg" alt="agent-tunnel" width="200"/>
155
95
  </a>
156
96
  </td>
157
- </tr>
158
- <tr>
159
97
  <td align="center">
160
98
  <a href="https://pchalasani.github.io/claude-code-tools/tools/lmsh/">
161
99
  <img src="assets/card-lmsh.svg" alt="lmsh" width="200"/>
@@ -166,13 +104,13 @@ Click a card to jump to that feature, or
166
104
  <img src="assets/card-vault.svg" alt="vault" width="200"/>
167
105
  </a>
168
106
  </td>
107
+ </tr>
108
+ <tr>
169
109
  <td align="center">
170
110
  <a href="https://pchalasani.github.io/claude-code-tools/tools/env-safe/">
171
111
  <img src="assets/card-env-safe.svg" alt="env-safe" width="200"/>
172
112
  </a>
173
113
  </td>
174
- </tr>
175
- <tr>
176
114
  <td align="center">
177
115
  <a href="https://pchalasani.github.io/claude-code-tools/plugins-detail/safety-hooks/">
178
116
  <img src="assets/card-safety.svg" alt="safety" width="200"/>
@@ -183,13 +121,13 @@ Click a card to jump to that feature, or
183
121
  <img src="assets/card-statusline.svg" alt="statusline" width="200"/>
184
122
  </a>
185
123
  </td>
124
+ </tr>
125
+ <tr>
186
126
  <td align="center">
187
127
  <a href="https://pchalasani.github.io/claude-code-tools/integrations/google-docs/">
188
128
  <img src="assets/card-gdocs.svg" alt="gdocs" width="200"/>
189
129
  </a>
190
130
  </td>
191
- </tr>
192
- <tr>
193
131
  <td align="center">
194
132
  <a href="https://pchalasani.github.io/claude-code-tools/integrations/google-sheets/">
195
133
  <img src="assets/card-gsheets.svg" alt="gsheets" width="200"/>
@@ -200,13 +138,13 @@ Click a card to jump to that feature, or
200
138
  <img src="assets/card-alt.svg" alt="alt" width="200"/>
201
139
  </a>
202
140
  </td>
141
+ </tr>
142
+ <tr>
203
143
  <td align="center">
204
144
  <a href="https://pchalasani.github.io/claude-code-tools/plugins-detail/voice/">
205
145
  <img src="assets/card-voice.svg" alt="voice" width="200"/>
206
146
  </a>
207
147
  </td>
208
- </tr>
209
- <tr>
210
148
  <td align="center">
211
149
  <a href="https://pchalasani.github.io/claude-code-tools/tools/fix-session/">
212
150
  <img src="assets/card-session-repair.svg" alt="session repair" width="200"/>
@@ -217,6 +155,8 @@ Click a card to jump to that feature, or
217
155
  <img src="assets/card-sasy-guard.svg" alt="sasy-guard" width="200"/>
218
156
  </a>
219
157
  </td>
158
+ </tr>
159
+ <tr>
220
160
  <td align="center">
221
161
  <a href="https://pchalasani.github.io/claude-code-tools/guides/claude-to-codex/">
222
162
  <img src="assets/card-claude-to-codex.svg" alt="Claude to Codex" width="200"/>
@@ -261,6 +201,13 @@ See [tmux-cli](https://pchalasani.github.io/claude-code-tools/tools/tmux-cli/) i
261
201
  ## Voice Plugin
262
202
  See [Voice](https://pchalasani.github.io/claude-code-tools/plugins-detail/voice/) in the full documentation.
263
203
 
204
+ <a id="voice-type"></a>
205
+ ## voice-type — Local Voice Dictation
206
+ Fully on-device speech-to-text (Moonshine + VAD) that types wherever your
207
+ cursor is, with a configurable toggle hotkey and optional wake word.
208
+ Install with `uv tool install "claude-code-tools[voice]"`.
209
+ See [voice-type](https://pchalasani.github.io/claude-code-tools/tools/voice-type/) in the full documentation.
210
+
264
211
  <a id="license"></a>
265
212
  ## License
266
213
 
@@ -1,3 +1,3 @@
1
1
  """Claude Code Tools - Collection of utilities for Claude Code."""
2
2
 
3
- __version__ = "1.17.0"
3
+ __version__ = "1.19.0"
@@ -37,7 +37,7 @@ class ResolveCommand(click.Command):
37
37
  """Parse arguments, converting Click usage failures to resolver errors."""
38
38
  import sys
39
39
 
40
- from claude_code_tools.resolve_session import _render_error
40
+ from claude_code_tools.resolve_session_render import _render_error
41
41
 
42
42
  raw_args = tuple(args)
43
43
  try:
@@ -115,9 +115,12 @@ def main(ctx, claude_home, codex_home):
115
115
  # Auto-index sessions on every aichat command (incremental, fast if up-to-date)
116
116
  # Skip for build-index/clear-index to avoid double-indexing or state conflicts
117
117
  # In JSON mode (-j/--json), suppress all output for clean parsing
118
+ # 'port' is also skipped: its contract requires the detected
119
+ # direction line to be the FIRST output, so the indexer's progress
120
+ # bar must never print before it.
118
121
  skip_auto_index_cmds = ['build-index', 'clear-index', 'index-stats']
119
122
  should_skip = (
120
- ctx.invoked_subcommand == 'resolve'
123
+ ctx.invoked_subcommand in ('port', 'resolve')
121
124
  or ctx.invoked_subcommand in skip_auto_index_cmds
122
125
  or any(cmd in sys.argv for cmd in skip_auto_index_cmds)
123
126
  )
@@ -182,10 +185,16 @@ def resolve_session_cmd(
182
185
  json_output: bool,
183
186
  pretty_output: bool,
184
187
  ) -> None:
185
- """Resolve a name, full session ID, or partial session ID."""
188
+ """Resolve a session name, full ID, ID fragment, or filename fragment.
189
+
190
+ Ordered tiers (first non-empty wins): exact ID, exact name, ID
191
+ prefix, ID substring, name substring, session-file name
192
+ substring (e.g. a codex rollout timestamp like
193
+ 2026-03-25T14-50).
194
+ """
186
195
  import sys
187
196
 
188
- from claude_code_tools.resolve_session import run
197
+ from claude_code_tools.resolve_session_render import run
189
198
 
190
199
  if json_output and pretty_output:
191
200
  click.echo(
@@ -1442,6 +1451,104 @@ def move_session(session, new_project, agent):
1442
1451
  console.print(f" [cyan]{resume_cmd}[/cyan]")
1443
1452
 
1444
1453
 
1454
+ @main.command("port")
1455
+ @click.argument("session", required=True)
1456
+ @click.option("--claude-home", help="Path to Claude home directory")
1457
+ @click.option("--codex-home", help="Path to Codex home directory")
1458
+ @click.pass_context
1459
+ def port_session(
1460
+ ctx: click.Context,
1461
+ session: str,
1462
+ claude_home: "str | None",
1463
+ codex_home: "str | None",
1464
+ ) -> None:
1465
+ """Port a session to the OTHER agent (codex <-> claude).
1466
+
1467
+ Auto-detects which agent the session belongs to. Codex sessions
1468
+ are converted into a flattened, resumable Claude Code session;
1469
+ Claude sessions are converted into a flattened, resumable Codex
1470
+ rollout.
1471
+
1472
+ SESSION may be a full session id, a partial id (prefix, middle,
1473
+ or suffix fragment), a session name (set with /rename), a
1474
+ rollout filename fragment (e.g. 2026-03-25T14-50), or a session
1475
+ file path. Lookup is global across all projects in both homes.
1476
+
1477
+ \b
1478
+ Examples:
1479
+ aichat port 019f6d85-df3c-7c83-84f6-b97e73305fcf
1480
+ aichat port abc123 --claude-home ~/.claude-alt
1481
+ aichat port my-session-name
1482
+ aichat port 2026-03-25T14-50
1483
+ """
1484
+ import sys
1485
+
1486
+ from claude_code_tools.port_service import (
1487
+ PortSessionError,
1488
+ port_claude_session,
1489
+ port_codex_session,
1490
+ resolve_port_session,
1491
+ )
1492
+
1493
+ # Group-level --claude-home/--codex-home (given BEFORE the
1494
+ # subcommand) are stored on the root context; command-level
1495
+ # options take precedence.
1496
+ root_obj = ctx.find_root().obj or {}
1497
+ claude_home = claude_home or root_obj.get("claude_home")
1498
+ codex_home = codex_home or root_obj.get("codex_home")
1499
+
1500
+ try:
1501
+ resolved = resolve_port_session(
1502
+ session, claude_home=claude_home, codex_home=codex_home
1503
+ )
1504
+ except PortSessionError as e:
1505
+ print(f"Error: {e}", file=sys.stderr)
1506
+ sys.exit(1)
1507
+
1508
+ if resolved.agent == "claude":
1509
+ print("Detected source agent: claude — porting to Codex")
1510
+ try:
1511
+ result = port_claude_session(
1512
+ resolved.session_file, codex_home=codex_home
1513
+ )
1514
+ except PortSessionError as e:
1515
+ print(f"Error: {e}", file=sys.stderr)
1516
+ sys.exit(1)
1517
+
1518
+ print()
1519
+ print(f"New Codex session id: {result.new_session_id}")
1520
+ print(f"Output file: {result.output_file}")
1521
+ print(f"Session cwd: {result.cwd}")
1522
+ print()
1523
+ print("To resume:")
1524
+ print(f" {result.resume_hint}")
1525
+ print()
1526
+ print(
1527
+ "Tip: codex's /import can also import Claude sessions "
1528
+ "natively (interactive alternative)."
1529
+ )
1530
+ return
1531
+
1532
+ print("Detected source agent: codex — porting to Claude Code")
1533
+ try:
1534
+ result = port_codex_session(
1535
+ resolved.session_file, claude_home=claude_home
1536
+ )
1537
+ except PortSessionError as e:
1538
+ # Expected failure modes (missing/empty session, filesystem
1539
+ # or encoding errors) become a clean error, not a traceback.
1540
+ print(f"Error: {e}", file=sys.stderr)
1541
+ sys.exit(1)
1542
+
1543
+ print()
1544
+ print(f"New Claude session id: {result.new_session_id}")
1545
+ print(f"Output file: {result.output_file}")
1546
+ print(f"Session cwd: {result.cwd}")
1547
+ print()
1548
+ print("To resume:")
1549
+ print(f" {result.resume_hint}")
1550
+
1551
+
1445
1552
  @main.command("query")
1446
1553
  @click.argument("session", required=False)
1447
1554
  @click.argument("question", required=False)
@@ -14,11 +14,13 @@ import struct
14
14
  import subprocess
15
15
  import sys
16
16
  import time
17
- from contextlib import contextmanager
17
+ from contextlib import ExitStack, contextmanager
18
18
  from dataclasses import replace
19
19
  from pathlib import Path
20
20
  from typing import Iterator, Mapping, Sequence
21
21
 
22
+ from claude_code_tools import codex_server_retry
23
+ from claude_code_tools.codex_server_legacy import reauthenticate_legacy_state
22
24
  from claude_code_tools.codex_server_fingerprint import (
23
25
  PluginSnapshot as _PluginSnapshot,
24
26
  hash_plugin_tree as _hash_plugin_tree, # noqa: F401
@@ -78,6 +80,7 @@ from claude_code_tools.codex_server_reuse import (
78
80
  disconnect_refusal as _disconnect_refusal,
79
81
  helper_restart_reason as _reuse_restart_reason,
80
82
  require_external_compatible as _external_compatible,
83
+ same_server_launch as _same_server_launch,
81
84
  )
82
85
 
83
86
 
@@ -150,6 +153,22 @@ def _lifecycle_lock(paths: ServerPaths) -> Iterator[None]:
150
153
  os.close(fd)
151
154
 
152
155
 
156
+ @contextmanager
157
+ def _reserved_generation_lifecycle(
158
+ base: ServerPaths,
159
+ paths: ServerPaths,
160
+ generation: str,
161
+ ) -> Iterator[None]:
162
+ """Reserve capacity before releasing the base lifecycle lock."""
163
+ generation_lock = ExitStack()
164
+ with _lifecycle_lock(base):
165
+ require_generation_capacity(base, generation)
166
+ prepare_runtime(paths)
167
+ generation_lock.enter_context(_lifecycle_lock(paths))
168
+ with generation_lock:
169
+ yield
170
+
171
+
153
172
  def _resolve_codex(env: Mapping[str, str]) -> str:
154
173
  """Resolve a canonical executable used by both server and TUI."""
155
174
  configured = env.get("CCTOOLS_CODEX_BIN")
@@ -519,6 +538,7 @@ def get_status(env: Mapping[str, str] | None = None) -> ServerStatus:
519
538
  except StateFileError as exc:
520
539
  state = None
521
540
  state_error = str(exc)
541
+ state = reauthenticate_legacy_state(paths, state, _socket_peer_pid)
522
542
  probe = _probe_server(codex_path, child_env, paths)
523
543
  return _status_from(paths, state, probe, state_error)
524
544
 
@@ -557,33 +577,12 @@ def _require_unchanged_plugin_snapshot(
557
577
  ) -> None:
558
578
  """Reject a lifecycle decision made across a plugin input change."""
559
579
  if _plugin_configuration_snapshot(paths, codex_options) != expected:
560
- raise CodexServerError(
580
+ raise codex_server_retry.PluginSnapshotChangedError(
561
581
  "the Codex plugin or marketplace snapshot changed during "
562
582
  f"{operation}; retry after plugin updates finish"
563
583
  )
564
584
 
565
585
 
566
- def _same_server_launch(expected: OwnedServer, current: OwnedServer) -> bool:
567
- """Return whether two states name the same exact supervised launch."""
568
- return (
569
- current.pid,
570
- current.pgid,
571
- current.process_started_at,
572
- current.launch_token,
573
- current.worker_pid,
574
- current.worker_pgid,
575
- current.worker_started_at,
576
- ) == (
577
- expected.pid,
578
- expected.pgid,
579
- expected.process_started_at,
580
- expected.launch_token,
581
- expected.worker_pid,
582
- expected.worker_pgid,
583
- expected.worker_started_at,
584
- )
585
-
586
-
587
586
  def _certify_helper_boundary(
588
587
  expected: OwnedServer,
589
588
  active_env: Mapping[str, str],
@@ -724,6 +723,7 @@ def _wait_for_process_group_exit(
724
723
  )
725
724
 
726
725
 
726
+ @codex_server_retry.retry_plugin_snapshot_changes
727
727
  def ensure_server(
728
728
  env: Mapping[str, str] | None = None,
729
729
  *,
@@ -745,16 +745,15 @@ def ensure_server(
745
745
  codex_options,
746
746
  )
747
747
  paths = paths_for_generation(base_paths, generation)
748
- require_generation_capacity(base_paths, generation)
749
- child_env = _command_env(active_env, paths)
750
- child_env[CODEX_SERVER_OPTIONS_ENV] = json.dumps(
751
- list(codex_options),
752
- separators=(",", ":"),
753
- )
754
- with _lifecycle_lock(paths):
748
+ with _reserved_generation_lifecycle(base_paths, paths, generation):
749
+ child_env = _command_env(active_env, paths)
750
+ child_env[CODEX_SERVER_OPTIONS_ENV] = json.dumps(
751
+ list(codex_options),
752
+ separators=(",", ":"),
753
+ )
755
754
  locked_snapshot = _plugin_configuration_snapshot(paths, codex_options)
756
755
  if locked_snapshot.fingerprint != plugin_snapshot.fingerprint:
757
- raise CodexServerError(
756
+ raise codex_server_retry.PluginSnapshotChangedError(
758
757
  "the Codex plugin or marketplace snapshot changed during "
759
758
  "app-server generation selection; retry after updates finish"
760
759
  )
@@ -766,6 +765,7 @@ def ensure_server(
766
765
  except StateFileError as exc:
767
766
  state = None
768
767
  state_error = str(exc)
768
+ state = reauthenticate_legacy_state(paths, state, _socket_peer_pid)
769
769
 
770
770
  probe = _probe_server(codex_path, child_env, paths)
771
771
  status = _status_from(paths, state, probe, state_error)
@@ -938,6 +938,7 @@ def _stop_server_at(
938
938
  ) from exc
939
939
  _quarantine_invalid_state(paths)
940
940
  state = None
941
+ state = reauthenticate_legacy_state(paths, state, _socket_peer_pid)
941
942
 
942
943
  if state is not None and _state_is_owned(state):
943
944
  if not allow_disconnect: