overcode 0.5.1__tar.gz → 0.5.4__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.
- overcode-0.5.4/MANIFEST.in +3 -0
- {overcode-0.5.1/src/overcode.egg-info → overcode-0.5.4}/PKG-INFO +12 -11
- {overcode-0.5.1 → overcode-0.5.4}/README.md +11 -10
- {overcode-0.5.1 → overcode-0.5.4}/pyproject.toml +11 -2
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/__init__.py +6 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/base.py +43 -1
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/claude_code.py +20 -1
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/codex.py +25 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/grok.py +24 -0
- overcode-0.5.4/src/overcode/backends/hermes.py +866 -0
- overcode-0.5.4/src/overcode/backends/hermes_stats.py +613 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/opencode.py +26 -0
- overcode-0.5.4/src/overcode/backends/opencode2.py +356 -0
- overcode-0.5.4/src/overcode/backends/opencode2_patterns.py +227 -0
- overcode-0.5.4/src/overcode/backends/opencode2_plugin_install.py +142 -0
- overcode-0.5.4/src/overcode/backends/opencode2_stats.py +629 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/opencode_stats.py +247 -32
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/__init__.py +1 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/_shared.py +7 -1
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/agent.py +2 -2
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/config.py +16 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/doctor.py +27 -34
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/hooks.py +30 -49
- overcode-0.5.4/src/overcode/cli/models.py +124 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/split.py +57 -13
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/config.py +27 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/daemon_claude_skill.md +23 -0
- overcode-0.5.4/src/overcode/data/model_metadata.json +982 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/doctor.py +17 -2
- overcode-0.5.4/src/overcode/entrypoint.py +40 -0
- overcode-0.5.4/src/overcode/hermes_plugin/__init__.py +327 -0
- overcode-0.5.4/src/overcode/hermes_plugin/plugin.yaml +22 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/history_reader.py +68 -13
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/launcher.py +57 -6
- overcode-0.5.4/src/overcode/model_metadata.py +556 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/monitor_daemon.py +111 -5
- overcode-0.5.4/src/overcode/opencode_plugin/overcode-telemetry-v2/index.js +21 -0
- overcode-0.5.4/src/overcode/opencode_plugin/overcode-telemetry-v2/overcode-telemetry-core.mjs +611 -0
- overcode-0.5.4/src/overcode/opencode_plugin/overcode-telemetry-v2/tui.js +103 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/pricing.py +34 -2
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/session_manager.py +71 -1
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/settings.py +14 -1
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/status_history.py +43 -26
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/summary_columns.py +2 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tmux_manager.py +9 -2
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui.py +173 -23
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/view.py +8 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_logic.py +68 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/wrapper.py +22 -10
- {overcode-0.5.1 → overcode-0.5.4/src/overcode.egg-info}/PKG-INFO +12 -11
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode.egg-info/SOURCES.txt +15 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode.egg-info/entry_points.txt +1 -1
- overcode-0.5.1/MANIFEST.in +0 -3
- {overcode-0.5.1 → overcode-0.5.4}/LICENSE +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/setup.cfg +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/__init__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/agent_scanner.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/codex_stats.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/backends/grok_stats.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/bundled_skills.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/claude_config.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/claude_pid.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/__main__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/budget.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/daemon.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/focal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/jobs.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/monitoring.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/parallelism.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/perms.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/sister.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/skills.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/tags.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/cli/wrappers.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/daemon_logging.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/daemon_utils.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/data_export.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/dependency_check.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/duration.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/exceptions.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/follow_mode.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/hook_handler.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/hook_status_detector.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/implementations.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/interfaces.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/job_launcher.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/job_manager.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/logging_config.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/mocks.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/monitor_daemon_core.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/monitor_daemon_state.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/notifier.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/opencode_plugin/overcode-telemetry.js +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/pid_utils.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/presence_logger.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/process_resources.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/protocols.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/sandbox_detect.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/sister_controller.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/sister_poller.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/ssh_provisioner.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/standing_instructions.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/stats_reader.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/status_constants.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/status_detector.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/status_detector_factory.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/status_patterns.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/summarizer_client.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/summarizer_component.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/summary_groups.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/supervisor_daemon.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/supervisor_daemon_core.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/supervisor_layout.sh +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/testing/__init__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/testing/renderer.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/testing/tmux_driver.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/testing/tui_eye.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/testing/tui_eye_skill.md +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/time_context.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tmux_utils.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui.tcss +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/__init__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/daemon.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/input.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/navigation.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_actions/session.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_helpers.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_render.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/__init__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/agent_select_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/command_bar.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/daemon_panel.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/daemon_status_bar.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/fullscreen_preview.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/help_overlay.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/instruction_history_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/job_summary.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/jump_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/modal_base.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/new_agent_defaults_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/new_agent_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/passthru_config_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/preview_pane.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/session_summary.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/sister_selection_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/status_timeline.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/summary_config_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/tmux_config_modal.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/tui_widgets/tui_log_panel.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/usage_monitor.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web/__init__.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web/templates/analytics.html +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web/templates/dashboard.html +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_api.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_chartjs.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_control_api.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_server.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_server_runner.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode/web_templates.py +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode.egg-info/dependency_links.txt +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode.egg-info/requires.txt +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/src/overcode.egg-info/top_level.txt +0 -0
- {overcode-0.5.1 → overcode-0.5.4}/tests/test_e2e_multi_agent_jokes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: overcode
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: A supervisor for managing multiple Claude Code instances in tmux
|
|
5
5
|
Author: Mike Bond
|
|
6
6
|
Project-URL: Homepage, https://github.com/mkb23/overcode
|
|
@@ -42,7 +42,7 @@ Dynamic: license-file
|
|
|
42
42
|
|
|
43
43
|
# overcode
|
|
44
44
|
|
|
45
|
-
A TUI supervisor for managing multiple coding agents (Claude Code, opencode, Codex, Grok) in tmux.
|
|
45
|
+
A TUI supervisor for managing multiple coding agents (Claude Code, opencode, opencode2, Codex, Grok, Hermes) in tmux.
|
|
46
46
|
|
|
47
47
|
Launch autonomous coding agents, monitor their progress in real-time, track costs and activity, and coordinate work across your projects—all from a single dashboard.
|
|
48
48
|
|
|
@@ -81,7 +81,7 @@ overcode tmux
|
|
|
81
81
|
|
|
82
82
|
This creates a split layout: the overcode dashboard on top, the focused agent's live terminal on the bottom. Navigate agents with `j/k` — the bottom pane follows automatically. Press `Tab` to toggle focus between panes.
|
|
83
83
|
|
|
84
|
-
**Requirements:** Python 3.12+, tmux, and an agent CLI — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [opencode](https://opencode.ai), [Codex CLI](https://github.com/openai/codex),
|
|
84
|
+
**Requirements:** Python 3.12+, tmux, and an agent CLI — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [opencode](https://opencode.ai) (v1, or the opencode2 2.0 preview), [Codex CLI](https://github.com/openai/codex), [Grok Build](https://x.ai), or [Hermes Agent](https://github.com/NousResearch/hermes-agent)
|
|
85
85
|
|
|
86
86
|
See the [Getting Started Guide](docs/getting-started.md) for a complete walkthrough.
|
|
87
87
|
|
|
@@ -129,14 +129,15 @@ Run agents in custom environments — containers, VMs, or any setup your project
|
|
|
129
129
|
See the [Wrappers Guide](docs/wrappers.md) for setup and customisation.
|
|
130
130
|
|
|
131
131
|
### Agent Backends
|
|
132
|
-
Overcode is not Claude-Code-only. It supports
|
|
133
|
-
Codex, and
|
|
134
|
-
opencode` (or `codex` / `grok`) and it appears in the
|
|
135
|
-
status, previews, AI summaries, send-instruction, restart,
|
|
136
|
-
token/cost/context columns
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
Overcode is not Claude-Code-only. It supports six agent CLIs today: Claude Code, opencode,
|
|
133
|
+
the opencode2 2.0 preview, Codex, Grok, and Hermes. Launch a non-default one with `overcode launch
|
|
134
|
+
-n my-agent --backend opencode` (or `opencode2` / `codex` / `grok` / `hermes`) and it appears in the
|
|
135
|
+
same dashboard with live hook-grade status, previews, AI summaries, send-instruction, restart,
|
|
136
|
+
kill, resume, and token/cost/context columns (fork where the CLI has one — opencode2's preview
|
|
137
|
+
TUI has no `--fork`, Hermes only branches in-session). Backends declare their capabilities, so
|
|
138
|
+
the Claude-only subsystems — skills, the sandbox badge, the subscription-usage widget, agent
|
|
139
|
+
teams — are hidden rather than shown as misleading zeros. A backend badge column appears only
|
|
140
|
+
when your fleet actually mixes backends, so a Claude-only setup looks exactly as it did. See the
|
|
140
141
|
[Backends Guide](docs/backends.md) for the full support matrix, flag mapping, and current
|
|
141
142
|
limitations.
|
|
142
143
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# overcode
|
|
2
2
|
|
|
3
|
-
A TUI supervisor for managing multiple coding agents (Claude Code, opencode, Codex, Grok) in tmux.
|
|
3
|
+
A TUI supervisor for managing multiple coding agents (Claude Code, opencode, opencode2, Codex, Grok, Hermes) in tmux.
|
|
4
4
|
|
|
5
5
|
Launch autonomous coding agents, monitor their progress in real-time, track costs and activity, and coordinate work across your projects—all from a single dashboard.
|
|
6
6
|
|
|
@@ -39,7 +39,7 @@ overcode tmux
|
|
|
39
39
|
|
|
40
40
|
This creates a split layout: the overcode dashboard on top, the focused agent's live terminal on the bottom. Navigate agents with `j/k` — the bottom pane follows automatically. Press `Tab` to toggle focus between panes.
|
|
41
41
|
|
|
42
|
-
**Requirements:** Python 3.12+, tmux, and an agent CLI — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [opencode](https://opencode.ai), [Codex CLI](https://github.com/openai/codex),
|
|
42
|
+
**Requirements:** Python 3.12+, tmux, and an agent CLI — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [opencode](https://opencode.ai) (v1, or the opencode2 2.0 preview), [Codex CLI](https://github.com/openai/codex), [Grok Build](https://x.ai), or [Hermes Agent](https://github.com/NousResearch/hermes-agent)
|
|
43
43
|
|
|
44
44
|
See the [Getting Started Guide](docs/getting-started.md) for a complete walkthrough.
|
|
45
45
|
|
|
@@ -87,14 +87,15 @@ Run agents in custom environments — containers, VMs, or any setup your project
|
|
|
87
87
|
See the [Wrappers Guide](docs/wrappers.md) for setup and customisation.
|
|
88
88
|
|
|
89
89
|
### Agent Backends
|
|
90
|
-
Overcode is not Claude-Code-only. It supports
|
|
91
|
-
Codex, and
|
|
92
|
-
opencode` (or `codex` / `grok`) and it appears in the
|
|
93
|
-
status, previews, AI summaries, send-instruction, restart,
|
|
94
|
-
token/cost/context columns
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
Overcode is not Claude-Code-only. It supports six agent CLIs today: Claude Code, opencode,
|
|
91
|
+
the opencode2 2.0 preview, Codex, Grok, and Hermes. Launch a non-default one with `overcode launch
|
|
92
|
+
-n my-agent --backend opencode` (or `opencode2` / `codex` / `grok` / `hermes`) and it appears in the
|
|
93
|
+
same dashboard with live hook-grade status, previews, AI summaries, send-instruction, restart,
|
|
94
|
+
kill, resume, and token/cost/context columns (fork where the CLI has one — opencode2's preview
|
|
95
|
+
TUI has no `--fork`, Hermes only branches in-session). Backends declare their capabilities, so
|
|
96
|
+
the Claude-only subsystems — skills, the sandbox badge, the subscription-usage widget, agent
|
|
97
|
+
teams — are hidden rather than shown as misleading zeros. A backend badge column appears only
|
|
98
|
+
when your fleet actually mixes backends, so a Claude-only setup looks exactly as it did. See the
|
|
98
99
|
[Backends Guide](docs/backends.md) for the full support matrix, flag mapping, and current
|
|
99
100
|
limitations.
|
|
100
101
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "overcode"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.4"
|
|
8
8
|
description = "A supervisor for managing multiple Claude Code instances in tmux"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Mike Bond"}
|
|
@@ -61,7 +61,7 @@ export = [
|
|
|
61
61
|
]
|
|
62
62
|
|
|
63
63
|
[project.scripts]
|
|
64
|
-
overcode = "overcode.
|
|
64
|
+
overcode = "overcode.entrypoint:main"
|
|
65
65
|
tui-eye = "overcode.testing.tui_eye:main"
|
|
66
66
|
|
|
67
67
|
[tool.setuptools.packages.find]
|
|
@@ -75,7 +75,16 @@ overcode = [
|
|
|
75
75
|
"web/templates/*.html",
|
|
76
76
|
# Bundled opencode telemetry plugin — copied into a project's
|
|
77
77
|
# .opencode/plugins/ at launch, so it has to ship with the wheel.
|
|
78
|
+
# v1 is a single .js file; v2 ships a plugin directory (server stub
|
|
79
|
+
# index.js + TUI entry tui.js + the shared core .mjs it imports).
|
|
78
80
|
"opencode_plugin/*.js",
|
|
81
|
+
"opencode_plugin/overcode-telemetry-v2/*",
|
|
82
|
+
# Bundled Hermes telemetry plugin — copied into $HERMES_HOME/plugins/
|
|
83
|
+
# overcode/ at launch (the .py ships as a module; the manifest must too).
|
|
84
|
+
"hermes_plugin/*.yaml",
|
|
85
|
+
# Bundled models.dev snapshot (context windows + list prices, #473) —
|
|
86
|
+
# refreshed by scripts/refresh_model_metadata.py.
|
|
87
|
+
"data/*.json",
|
|
79
88
|
]
|
|
80
89
|
|
|
81
90
|
[tool.black]
|
|
@@ -17,15 +17,19 @@ from .base import (
|
|
|
17
17
|
from .claude_code import ClaudeCodeBackend
|
|
18
18
|
from .codex import CodexBackend
|
|
19
19
|
from .grok import GrokBackend
|
|
20
|
+
from .hermes import HermesBackend
|
|
20
21
|
from .opencode import OpencodeBackend
|
|
22
|
+
from .opencode2 import Opencode2Backend
|
|
21
23
|
|
|
22
24
|
DEFAULT_BACKEND = "claude-code"
|
|
23
25
|
|
|
24
26
|
_BACKENDS: Dict[str, AgentBackend] = {
|
|
25
27
|
ClaudeCodeBackend.name: ClaudeCodeBackend(),
|
|
26
28
|
OpencodeBackend.name: OpencodeBackend(),
|
|
29
|
+
Opencode2Backend.name: Opencode2Backend(),
|
|
27
30
|
CodexBackend.name: CodexBackend(),
|
|
28
31
|
GrokBackend.name: GrokBackend(),
|
|
32
|
+
HermesBackend.name: HermesBackend(),
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
|
|
@@ -151,7 +155,9 @@ __all__ = [
|
|
|
151
155
|
"ClaudeCodeBackend",
|
|
152
156
|
"CodexBackend",
|
|
153
157
|
"GrokBackend",
|
|
158
|
+
"HermesBackend",
|
|
154
159
|
"OpencodeBackend",
|
|
160
|
+
"Opencode2Backend",
|
|
155
161
|
"DEFAULT_BACKEND",
|
|
156
162
|
"DialogRule",
|
|
157
163
|
"KeyPress",
|
|
@@ -35,6 +35,7 @@ class BackendCapability(Flag):
|
|
|
35
35
|
HOOK_EVENTS = auto() # push telemetry (hook-state files) available
|
|
36
36
|
TRANSCRIPT_STATS = auto() # tokens/cost/context readable from disk
|
|
37
37
|
PERMISSION_INJECTION = auto() # per-launch permission allowlist
|
|
38
|
+
AGENT_INJECTION = auto() # launch-time persona/agent flag (--agent) is honored
|
|
38
39
|
SKILLS = auto() # skills/persona file discovery
|
|
39
40
|
SANDBOX_PROBE = auto()
|
|
40
41
|
SUBSCRIPTION_USAGE = auto()
|
|
@@ -107,7 +108,7 @@ class LaunchSpec:
|
|
|
107
108
|
class AgentBackend(Protocol):
|
|
108
109
|
"""Adapter for one agent CLI."""
|
|
109
110
|
|
|
110
|
-
name: str # "claude-code" | "opencode" | "codex" | "grok"
|
|
111
|
+
name: str # "claude-code" | "opencode" | "opencode2" | "codex" | "grok" | "hermes"
|
|
111
112
|
display_name: str
|
|
112
113
|
binary: str # for dependency_check + doctor process matching
|
|
113
114
|
version_args: Sequence[str]
|
|
@@ -136,6 +137,16 @@ class AgentBackend(Protocol):
|
|
|
136
137
|
# default documents the fallback, it isn't inherited automatically.)
|
|
137
138
|
fork_prescribes_new_session_id: bool = False
|
|
138
139
|
|
|
140
|
+
# Optional. Substrings that identify the agent's live process by argv when
|
|
141
|
+
# its basename is not distinctive — hermes runs as Hermes's own venv
|
|
142
|
+
# python (`.../venv/bin/python .../hermes-agent/hermes --cli`), so
|
|
143
|
+
# matching ``process_basenames`` alone would have to match "python".
|
|
144
|
+
# ``doctor.find_agent_process`` reads this via ``getattr`` and accepts a
|
|
145
|
+
# process whose basename is in ``process_basenames`` OR whose argv
|
|
146
|
+
# contains any marker. Same "not inherited from the Protocol" caveat as
|
|
147
|
+
# fork_prescribes_new_session_id above.
|
|
148
|
+
process_argv_markers: Sequence[str] = ()
|
|
149
|
+
|
|
139
150
|
def build_command(self, spec: LaunchSpec) -> List[str]: ...
|
|
140
151
|
|
|
141
152
|
def prepare_launch(self, spec: LaunchSpec) -> None:
|
|
@@ -165,6 +176,37 @@ class AgentBackend(Protocol):
|
|
|
165
176
|
|
|
166
177
|
def prompt_ready_chars(self) -> Set[str]: ...
|
|
167
178
|
|
|
179
|
+
def prompt_ready_line(self, line: str) -> bool:
|
|
180
|
+
"""Optional. Is this (ANSI-stripped, whitespace-trimmed) pane line the
|
|
181
|
+
live, empty input prompt?
|
|
182
|
+
|
|
183
|
+
``launcher._wait_for_prompt`` consults this via ``getattr`` before
|
|
184
|
+
falling back to an exact match against ``prompt_ready_chars()``. The
|
|
185
|
+
exact-set form can't express a prompt that is never drawn bare —
|
|
186
|
+
hermes always follows its glyph with a rotating placeholder hint —
|
|
187
|
+
so a backend with that shape implements this instead.
|
|
188
|
+
"""
|
|
189
|
+
...
|
|
190
|
+
|
|
191
|
+
def uninstall_telemetry(self, project_dir: Optional[str] = None) -> Tuple[bool, str]:
|
|
192
|
+
"""Optional. Remove this backend's on-disk telemetry footprint.
|
|
193
|
+
|
|
194
|
+
Backs ``overcode hooks uninstall-backend <name>``. Returns ``(ok,
|
|
195
|
+
message)``: ``ok`` False means the footprint was found but *not*
|
|
196
|
+
removed (not overcode-managed, or ``project_dir`` was needed and
|
|
197
|
+
missing) and the CLI exits non-zero. A backend whose telemetry
|
|
198
|
+
leaves nothing on disk (Claude Code's ``--settings``, codex's ``-c``
|
|
199
|
+
overrides) returns ``(True, "nothing installed on disk …")``.
|
|
200
|
+
"""
|
|
201
|
+
...
|
|
202
|
+
|
|
203
|
+
def doctor_findings(self) -> List[str]:
|
|
204
|
+
"""Optional. Fleet-level warnings for ``overcode doctor`` — version
|
|
205
|
+
outside the tested range, missing auth, stats-store schema drift.
|
|
206
|
+
Only called when the fleet actually has an agent on this backend.
|
|
207
|
+
"""
|
|
208
|
+
...
|
|
209
|
+
|
|
168
210
|
def status_patterns(self) -> "StatusPatterns": ...
|
|
169
211
|
|
|
170
212
|
def make_stats_reader(self) -> "StatsReader": ...
|
|
@@ -99,6 +99,7 @@ class ClaudeCodeBackend:
|
|
|
99
99
|
| BackendCapability.HOOK_EVENTS
|
|
100
100
|
| BackendCapability.TRANSCRIPT_STATS
|
|
101
101
|
| BackendCapability.PERMISSION_INJECTION
|
|
102
|
+
| BackendCapability.AGENT_INJECTION
|
|
102
103
|
| BackendCapability.SKILLS
|
|
103
104
|
| BackendCapability.SANDBOX_PROBE
|
|
104
105
|
| BackendCapability.SUBSCRIPTION_USAGE
|
|
@@ -218,7 +219,21 @@ class ClaudeCodeBackend:
|
|
|
218
219
|
|
|
219
220
|
def startup_dialog_rules(self) -> List[DialogRule]:
|
|
220
221
|
return [
|
|
221
|
-
# Trust prompt
|
|
222
|
+
# Trust prompt, Claude Code ≥ 2.1.27x (seen live Sep 19 2026,
|
|
223
|
+
# v2.1.274/278): "Accessing workspace: … ❯ No, exit / Yes, I
|
|
224
|
+
# trust this folder" — the safe option is preselected and a
|
|
225
|
+
# bare Enter leaves the dialog up (verified live), so navigate
|
|
226
|
+
# Down to the trust line first. Listed before the legacy rule
|
|
227
|
+
# so it wins whenever the "❯ No, exit" cursor line is present.
|
|
228
|
+
DialogRule(
|
|
229
|
+
marker="❯ No, exit",
|
|
230
|
+
presses=[
|
|
231
|
+
KeyPress("Down", enter=False, delay_after=0.3),
|
|
232
|
+
KeyPress("", enter=True),
|
|
233
|
+
],
|
|
234
|
+
settle_seconds=1.5,
|
|
235
|
+
),
|
|
236
|
+
# Trust prompt, older builds: accept was preselected, just Enter
|
|
222
237
|
DialogRule(
|
|
223
238
|
marker="I trust this folder",
|
|
224
239
|
presses=[KeyPress("", enter=True)],
|
|
@@ -247,6 +262,10 @@ class ClaudeCodeBackend:
|
|
|
247
262
|
from ..stats_reader import ClaudeStatsReader
|
|
248
263
|
return ClaudeStatsReader()
|
|
249
264
|
|
|
265
|
+
def uninstall_telemetry(self, project_dir: Optional[str] = None) -> Tuple[bool, str]:
|
|
266
|
+
"""Nothing on disk: telemetry rides on per-launch argv (see cli/hooks.py)."""
|
|
267
|
+
return True, f"nothing installed on disk for this backend ({self.name})"
|
|
268
|
+
|
|
250
269
|
def health_verdict(self, argv: str) -> Tuple[str, str]:
|
|
251
270
|
"""Hooks reach Claude Code only via the injected --settings payload."""
|
|
252
271
|
from ..doctor import VERDICT_MISSING_SETTINGS, VERDICT_OK
|
|
@@ -446,6 +446,23 @@ class CodexBackend:
|
|
|
446
446
|
# continue"), which persists trust per-path in ~/.codex/config.toml
|
|
447
447
|
# so a revisited directory shows no dialog at all.
|
|
448
448
|
return [
|
|
449
|
+
# Seen live on codex 0.153.4 (Sep 19 2026) when 0.155.1 was out,
|
|
450
|
+
# drawn BEFORE the trust dialog:
|
|
451
|
+
# ✨ Update available! 0.153.4 -> 0.155.1
|
|
452
|
+
# › 1. Update now (runs `npm install -g @openai/codex`)
|
|
453
|
+
# 2. Skip
|
|
454
|
+
# 3. Skip until next version
|
|
455
|
+
# Press enter to continue
|
|
456
|
+
# The preselected option runs a global npm install, so a bare
|
|
457
|
+
# Enter here (or a supervisor's `approve` gesture) would start
|
|
458
|
+
# upgrading the CLI under the agent. Digits select immediately
|
|
459
|
+
# in this widget (verified on the trust dialog, same widget):
|
|
460
|
+
# "2" skips for this launch only and persists nothing.
|
|
461
|
+
DialogRule(
|
|
462
|
+
marker="Update available!",
|
|
463
|
+
presses=[KeyPress("2", enter=False)],
|
|
464
|
+
settle_seconds=1.5,
|
|
465
|
+
),
|
|
449
466
|
DialogRule(
|
|
450
467
|
marker="Do you trust the contents of this directory?",
|
|
451
468
|
presses=[KeyPress("", enter=True)],
|
|
@@ -489,6 +506,14 @@ class CodexBackend:
|
|
|
489
506
|
"not fire. Relaunch via `overcode restart` to re-inject."
|
|
490
507
|
)
|
|
491
508
|
|
|
509
|
+
def uninstall_telemetry(self, project_dir: Optional[str] = None) -> Tuple[bool, str]:
|
|
510
|
+
"""Nothing on disk: telemetry rides on per-launch argv (see cli/hooks.py)."""
|
|
511
|
+
return True, f"nothing installed on disk for this backend ({self.name})"
|
|
512
|
+
|
|
513
|
+
def doctor_findings(self) -> List[str]:
|
|
514
|
+
"""Fleet-level warnings for ``overcode doctor`` (see cli/doctor.py)."""
|
|
515
|
+
return version_findings()
|
|
516
|
+
|
|
492
517
|
def check_binary(self):
|
|
493
518
|
from ..dependency_check import check_agent_cli
|
|
494
519
|
return check_agent_cli(self)
|
|
@@ -508,6 +508,7 @@ class GrokBackend:
|
|
|
508
508
|
| BackendCapability.FORK
|
|
509
509
|
| BackendCapability.SESSION_ID_PRESCRIPTION
|
|
510
510
|
| BackendCapability.PERMISSION_INJECTION
|
|
511
|
+
| BackendCapability.AGENT_INJECTION
|
|
511
512
|
| BackendCapability.HOOK_EVENTS
|
|
512
513
|
| BackendCapability.TRANSCRIPT_STATS
|
|
513
514
|
)
|
|
@@ -747,6 +748,29 @@ class GrokBackend:
|
|
|
747
748
|
"restart` to install it."
|
|
748
749
|
)
|
|
749
750
|
|
|
751
|
+
def uninstall_telemetry(self, project_dir: Optional[str] = None) -> Tuple[bool, str]:
|
|
752
|
+
"""Remove the global hooks file if it is ours (see cli/hooks.py)."""
|
|
753
|
+
import json
|
|
754
|
+
|
|
755
|
+
path = hooks_file_path()
|
|
756
|
+
try:
|
|
757
|
+
existing = json.loads(path.read_text(encoding="utf-8"))
|
|
758
|
+
except OSError:
|
|
759
|
+
return True, f"No grok hooks file found at {path}"
|
|
760
|
+
except (ValueError, TypeError):
|
|
761
|
+
return False, f"{path} is not valid JSON — leaving it alone"
|
|
762
|
+
if not _is_ours(existing):
|
|
763
|
+
return False, f"{path} exists but is not overcode-managed — leaving it alone"
|
|
764
|
+
try:
|
|
765
|
+
path.unlink()
|
|
766
|
+
except OSError as exc:
|
|
767
|
+
return False, f"could not remove {path}: {exc}"
|
|
768
|
+
return True, f"Removed {path}"
|
|
769
|
+
|
|
770
|
+
def doctor_findings(self) -> List[str]:
|
|
771
|
+
"""Fleet-level warnings for ``overcode doctor`` (see cli/doctor.py)."""
|
|
772
|
+
return version_findings()
|
|
773
|
+
|
|
750
774
|
def check_binary(self):
|
|
751
775
|
from ..dependency_check import check_agent_cli
|
|
752
776
|
return check_agent_cli(self)
|