overcode 0.2.6__tar.gz → 0.3.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 (116) hide show
  1. {overcode-0.2.6/src/overcode.egg-info → overcode-0.3.0}/PKG-INFO +37 -20
  2. {overcode-0.2.6 → overcode-0.3.0}/README.md +36 -19
  3. {overcode-0.2.6 → overcode-0.3.0}/pyproject.toml +1 -1
  4. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/claude_config.py +43 -47
  5. overcode-0.3.0/src/overcode/claude_pid.py +38 -0
  6. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/__init__.py +1 -0
  7. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/agent.py +163 -100
  8. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/budget.py +10 -0
  9. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/config.py +5 -1
  10. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/daemon.py +56 -37
  11. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/monitoring.py +17 -7
  12. overcode-0.3.0/src/overcode/cli/split.py +798 -0
  13. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/config.py +89 -42
  14. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/daemon_logging.py +13 -8
  15. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/daemon_utils.py +2 -41
  16. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/data_export.py +60 -59
  17. overcode-0.3.0/src/overcode/dependency_check.py +132 -0
  18. overcode-0.3.0/src/overcode/duration.py +28 -0
  19. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/follow_mode.py +69 -61
  20. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/hook_handler.py +5 -1
  21. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/hook_status_detector.py +35 -48
  22. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/implementations.py +4 -61
  23. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/launcher.py +192 -122
  24. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/logging_config.py +8 -10
  25. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/monitor_daemon.py +21 -6
  26. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/monitor_daemon_state.py +5 -2
  27. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/notifier.py +11 -18
  28. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/pid_utils.py +19 -17
  29. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/presence_logger.py +3 -7
  30. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/session_manager.py +81 -75
  31. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/settings.py +57 -52
  32. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/sister_controller.py +10 -0
  33. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/sister_poller.py +14 -9
  34. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/standing_instructions.py +7 -3
  35. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/status_constants.py +59 -61
  36. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/status_detector.py +234 -133
  37. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/status_detector_factory.py +6 -1
  38. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/status_patterns.py +42 -3
  39. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/summarizer_client.py +1 -1
  40. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/summarizer_component.py +2 -1
  41. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/summary_columns.py +65 -62
  42. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/supervisor_daemon.py +132 -117
  43. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/supervisor_daemon_core.py +0 -38
  44. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/time_context.py +12 -6
  45. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tmux_manager.py +8 -96
  46. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tmux_utils.py +102 -9
  47. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui.py +503 -35
  48. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui.tcss +42 -2
  49. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/daemon.py +21 -48
  50. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/input.py +60 -78
  51. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/session.py +56 -32
  52. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/view.py +44 -16
  53. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_helpers.py +36 -0
  54. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_logic.py +70 -17
  55. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_render.py +17 -9
  56. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/__init__.py +2 -0
  57. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/agent_select_modal.py +9 -6
  58. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/command_bar.py +5 -0
  59. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/daemon_status_bar.py +15 -3
  60. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/fullscreen_preview.py +7 -4
  61. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/help_overlay.py +45 -28
  62. overcode-0.3.0/src/overcode/tui_widgets/instruction_history_modal.py +164 -0
  63. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/new_agent_defaults_modal.py +9 -6
  64. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/preview_pane.py +5 -2
  65. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/session_summary.py +4 -10
  66. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/sister_selection_modal.py +9 -6
  67. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/summary_config_modal.py +11 -8
  68. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_api.py +96 -96
  69. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_control_api.py +35 -4
  70. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_server.py +183 -187
  71. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_server_runner.py +1 -1
  72. {overcode-0.2.6 → overcode-0.3.0/src/overcode.egg-info}/PKG-INFO +37 -20
  73. {overcode-0.2.6 → overcode-0.3.0}/src/overcode.egg-info/SOURCES.txt +4 -0
  74. overcode-0.2.6/src/overcode/dependency_check.py +0 -111
  75. {overcode-0.2.6 → overcode-0.3.0}/LICENSE +0 -0
  76. {overcode-0.2.6 → overcode-0.3.0}/MANIFEST.in +0 -0
  77. {overcode-0.2.6 → overcode-0.3.0}/setup.cfg +0 -0
  78. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/__init__.py +0 -0
  79. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/agent_scanner.py +0 -0
  80. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/bundled_skills.py +0 -0
  81. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/__main__.py +0 -0
  82. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/_shared.py +0 -0
  83. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/hooks.py +0 -0
  84. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/perms.py +0 -0
  85. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/sister.py +0 -0
  86. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/cli/skills.py +0 -0
  87. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/daemon_claude_skill.md +0 -0
  88. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/exceptions.py +0 -0
  89. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/history_reader.py +0 -0
  90. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/interfaces.py +0 -0
  91. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/mocks.py +0 -0
  92. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/monitor_daemon_core.py +0 -0
  93. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/protocols.py +0 -0
  94. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/status_history.py +0 -0
  95. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/summary_groups.py +0 -0
  96. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/supervisor_layout.sh +0 -0
  97. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/testing/__init__.py +0 -0
  98. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/testing/renderer.py +0 -0
  99. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/testing/tmux_driver.py +0 -0
  100. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/testing/tui_eye.py +0 -0
  101. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/testing/tui_eye_skill.md +0 -0
  102. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/__init__.py +0 -0
  103. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_actions/navigation.py +0 -0
  104. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/daemon_panel.py +0 -0
  105. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/tui_widgets/status_timeline.py +0 -0
  106. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/usage_monitor.py +0 -0
  107. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web/__init__.py +0 -0
  108. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web/templates/analytics.html +0 -0
  109. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web/templates/dashboard.html +0 -0
  110. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_chartjs.py +0 -0
  111. {overcode-0.2.6 → overcode-0.3.0}/src/overcode/web_templates.py +0 -0
  112. {overcode-0.2.6 → overcode-0.3.0}/src/overcode.egg-info/dependency_links.txt +0 -0
  113. {overcode-0.2.6 → overcode-0.3.0}/src/overcode.egg-info/entry_points.txt +0 -0
  114. {overcode-0.2.6 → overcode-0.3.0}/src/overcode.egg-info/requires.txt +0 -0
  115. {overcode-0.2.6 → overcode-0.3.0}/src/overcode.egg-info/top_level.txt +0 -0
  116. {overcode-0.2.6 → overcode-0.3.0}/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.2.6
3
+ Version: 0.3.0
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
@@ -51,21 +51,16 @@ Launch autonomous coding agents, monitor their progress in real-time, track cost
51
51
  Running multiple Claude Code agents is powerful, but managing them gets chaotic fast. Overcode solves this by giving you:
52
52
 
53
53
  - **Unified visibility** - See all agents at a glance: what they're working on, whether they need input, and how much they're costing you
54
+ - **Native tmux integration** - A split layout with your dashboard on top and the focused agent's live terminal below—full speed, full color, full scrollback
54
55
  - **Smart orchestration** - An optional supervisor daemon can approve prompts and keep agents moving without constant attention
55
- - **Efficiency metrics** - Track "green time" (Claude actively working) vs idle time to understand where time goes
56
+ - **Multi-machine monitoring** - Sister integration aggregates agents from multiple machines into one view
56
57
  - **Session persistence** - Agents run in tmux, surviving terminal disconnects. Pick up where you left off
57
58
 
58
- ## Screenshots
59
+ ## Screenshot
59
60
 
60
- **Split-screen with tmux sync** - Monitor agents in the top pane while viewing live agent output below. Press `p` to enable pane sync, then navigate with `j/k` to switch the bottom pane to the selected agent's window.
61
+ **Tmux split layout** Monitor all agents in the top pane. The bottom pane shows the selected agent's live terminal. Navigate with `j/k` and the bottom pane follows. Press `Tab` to switch focus between panes.
61
62
 
62
- ![Overcode split-screen with tmux sync](docs/images/overcode-split-screen.png)
63
-
64
- > **iTerm2 setup**: Use `Cmd+Shift+D` to split horizontally. Run `overcode monitor` in the top pane and `tmux attach -t agents` in the bottom pane.
65
-
66
- **Preview mode** - Press `m` to toggle List+Preview mode. Shows collapsed agent list with detailed terminal output preview for the selected agent.
67
-
68
- ![Overcode preview mode](docs/images/overcode-preview-mode.png)
63
+ ![Overcode v0.3.0 tmux split layout](docs/screenshots/overcode-v0p3p0.jpg)
69
64
 
70
65
  ## Quick Start
71
66
 
@@ -75,16 +70,32 @@ Try it instantly with [uvx](https://docs.astral.sh/uv/):
75
70
  uvx overcode monitor
76
71
  ```
77
72
 
78
- This opens the dashboard. Press `n` to create your first agent—give it a name, point it at a project directory, and optionally provide an initial prompt. Create a few agents to see them work in parallel.
73
+ This opens the standalone dashboard. Press `n` to create your first agent.
79
74
 
80
- **Requirements:** Python 3.12+, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
75
+ For the full tmux-native experience (recommended):
81
76
 
82
- For permanent installation: `pip install overcode`
77
+ ```bash
78
+ pip install overcode
79
+ overcode tmux
80
+ ```
81
+
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
+
84
+ **Requirements:** Python 3.12+, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
83
85
 
84
86
  See the [Getting Started Guide](docs/getting-started.md) for a complete walkthrough.
85
87
 
86
88
  ## Features
87
89
 
90
+ ### Tmux Split Layout (`overcode tmux`)
91
+ The recommended way to use overcode. Creates a two-pane layout in tmux:
92
+ - **Top pane**: Compact agent dashboard with live status
93
+ - **Bottom pane**: The focused agent's native terminal — no emulation, real tmux
94
+ - `j/k` navigates agents, bottom pane follows
95
+ - `Tab` toggles focus between dashboard and terminal
96
+ - `Option+J/K` navigates agents from the terminal pane
97
+ - `PageUp/Down` and mouse scroll work in the bottom pane
98
+
88
99
  ### Real-time Dashboard
89
100
  The TUI displays all agents with live status updates, showing:
90
101
  - Current activity and AI-generated summaries
@@ -97,8 +108,9 @@ The TUI displays all agents with live status updates, showing:
97
108
  - **Launch agents** with custom prompts and permission settings
98
109
  - **Send instructions** directly from the dashboard
99
110
  - **Standing orders** - persistent instructions that guide agent behavior
111
+ - **Agent hierarchy** - parent/child delegation with follow mode and reporting
112
+ - **Cost budgets** - per-agent spending limits with automatic enforcement
100
113
  - **Sleep mode** - pause agents and exclude them from stats
101
- - **Priority sorting** - organize agents by importance
102
114
 
103
115
  ### Supervisor Daemon
104
116
  An optional Claude-powered orchestrator that:
@@ -107,26 +119,31 @@ An optional Claude-powered orchestrator that:
107
119
  - Follows per-agent standing orders
108
120
  - Tracks interventions and steering decisions
109
121
 
122
+ ### Sister Integration
123
+ Aggregate agents from multiple machines into one dashboard:
124
+ - Configure sister machines in `~/.overcode/config.yaml`
125
+ - Remote agents appear alongside local ones
126
+ - In tmux split mode, selecting a sister agent auto-zooms the dashboard with a preview pane
127
+
110
128
  ### Analytics & Export
111
129
  - **Web dashboard** - mobile-friendly monitoring from any device
112
130
  - **Historical analytics** - browse session history with charts
113
131
  - **Parquet export** - analyze data in Jupyter notebooks
114
- - **Presence tracking** - correlate activity with your availability (macOS)
132
+ - **Presence tracking** - correlate activity with your availability
115
133
 
116
134
  ## TUI Controls
117
135
 
118
136
  | Key | Action |
119
137
  |-----|--------|
120
138
  | `j/k` or `↑/↓` | Navigate agents |
139
+ | `Tab` | Toggle dashboard/terminal focus (tmux split) |
121
140
  | `Enter` | Approve/send Enter to agent |
122
141
  | `i` or `:` | Send instruction |
123
- | `m` | Toggle list+preview mode |
124
- | `t` | Toggle timeline |
125
- | `z` | Toggle sleep mode |
142
+ | `n` | Create new agent |
126
143
  | `x` | Kill agent (double-press) |
127
144
  | `b` | Jump to next agent needing attention |
128
145
  | `h` or `?` | Show all shortcuts |
129
- | `q` | Quit |
146
+ | `q` | Quit (or detach in tmux split) |
130
147
 
131
148
  See the [TUI Guide](docs/tui-guide.md) for all keyboard shortcuts.
132
149
 
@@ -9,21 +9,16 @@ Launch autonomous coding agents, monitor their progress in real-time, track cost
9
9
  Running multiple Claude Code agents is powerful, but managing them gets chaotic fast. Overcode solves this by giving you:
10
10
 
11
11
  - **Unified visibility** - See all agents at a glance: what they're working on, whether they need input, and how much they're costing you
12
+ - **Native tmux integration** - A split layout with your dashboard on top and the focused agent's live terminal below—full speed, full color, full scrollback
12
13
  - **Smart orchestration** - An optional supervisor daemon can approve prompts and keep agents moving without constant attention
13
- - **Efficiency metrics** - Track "green time" (Claude actively working) vs idle time to understand where time goes
14
+ - **Multi-machine monitoring** - Sister integration aggregates agents from multiple machines into one view
14
15
  - **Session persistence** - Agents run in tmux, surviving terminal disconnects. Pick up where you left off
15
16
 
16
- ## Screenshots
17
+ ## Screenshot
17
18
 
18
- **Split-screen with tmux sync** - Monitor agents in the top pane while viewing live agent output below. Press `p` to enable pane sync, then navigate with `j/k` to switch the bottom pane to the selected agent's window.
19
+ **Tmux split layout** Monitor all agents in the top pane. The bottom pane shows the selected agent's live terminal. Navigate with `j/k` and the bottom pane follows. Press `Tab` to switch focus between panes.
19
20
 
20
- ![Overcode split-screen with tmux sync](docs/images/overcode-split-screen.png)
21
-
22
- > **iTerm2 setup**: Use `Cmd+Shift+D` to split horizontally. Run `overcode monitor` in the top pane and `tmux attach -t agents` in the bottom pane.
23
-
24
- **Preview mode** - Press `m` to toggle List+Preview mode. Shows collapsed agent list with detailed terminal output preview for the selected agent.
25
-
26
- ![Overcode preview mode](docs/images/overcode-preview-mode.png)
21
+ ![Overcode v0.3.0 tmux split layout](docs/screenshots/overcode-v0p3p0.jpg)
27
22
 
28
23
  ## Quick Start
29
24
 
@@ -33,16 +28,32 @@ Try it instantly with [uvx](https://docs.astral.sh/uv/):
33
28
  uvx overcode monitor
34
29
  ```
35
30
 
36
- This opens the dashboard. Press `n` to create your first agent—give it a name, point it at a project directory, and optionally provide an initial prompt. Create a few agents to see them work in parallel.
31
+ This opens the standalone dashboard. Press `n` to create your first agent.
37
32
 
38
- **Requirements:** Python 3.12+, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
33
+ For the full tmux-native experience (recommended):
39
34
 
40
- For permanent installation: `pip install overcode`
35
+ ```bash
36
+ pip install overcode
37
+ overcode tmux
38
+ ```
39
+
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
+
42
+ **Requirements:** Python 3.12+, tmux, [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
41
43
 
42
44
  See the [Getting Started Guide](docs/getting-started.md) for a complete walkthrough.
43
45
 
44
46
  ## Features
45
47
 
48
+ ### Tmux Split Layout (`overcode tmux`)
49
+ The recommended way to use overcode. Creates a two-pane layout in tmux:
50
+ - **Top pane**: Compact agent dashboard with live status
51
+ - **Bottom pane**: The focused agent's native terminal — no emulation, real tmux
52
+ - `j/k` navigates agents, bottom pane follows
53
+ - `Tab` toggles focus between dashboard and terminal
54
+ - `Option+J/K` navigates agents from the terminal pane
55
+ - `PageUp/Down` and mouse scroll work in the bottom pane
56
+
46
57
  ### Real-time Dashboard
47
58
  The TUI displays all agents with live status updates, showing:
48
59
  - Current activity and AI-generated summaries
@@ -55,8 +66,9 @@ The TUI displays all agents with live status updates, showing:
55
66
  - **Launch agents** with custom prompts and permission settings
56
67
  - **Send instructions** directly from the dashboard
57
68
  - **Standing orders** - persistent instructions that guide agent behavior
69
+ - **Agent hierarchy** - parent/child delegation with follow mode and reporting
70
+ - **Cost budgets** - per-agent spending limits with automatic enforcement
58
71
  - **Sleep mode** - pause agents and exclude them from stats
59
- - **Priority sorting** - organize agents by importance
60
72
 
61
73
  ### Supervisor Daemon
62
74
  An optional Claude-powered orchestrator that:
@@ -65,26 +77,31 @@ An optional Claude-powered orchestrator that:
65
77
  - Follows per-agent standing orders
66
78
  - Tracks interventions and steering decisions
67
79
 
80
+ ### Sister Integration
81
+ Aggregate agents from multiple machines into one dashboard:
82
+ - Configure sister machines in `~/.overcode/config.yaml`
83
+ - Remote agents appear alongside local ones
84
+ - In tmux split mode, selecting a sister agent auto-zooms the dashboard with a preview pane
85
+
68
86
  ### Analytics & Export
69
87
  - **Web dashboard** - mobile-friendly monitoring from any device
70
88
  - **Historical analytics** - browse session history with charts
71
89
  - **Parquet export** - analyze data in Jupyter notebooks
72
- - **Presence tracking** - correlate activity with your availability (macOS)
90
+ - **Presence tracking** - correlate activity with your availability
73
91
 
74
92
  ## TUI Controls
75
93
 
76
94
  | Key | Action |
77
95
  |-----|--------|
78
96
  | `j/k` or `↑/↓` | Navigate agents |
97
+ | `Tab` | Toggle dashboard/terminal focus (tmux split) |
79
98
  | `Enter` | Approve/send Enter to agent |
80
99
  | `i` or `:` | Send instruction |
81
- | `m` | Toggle list+preview mode |
82
- | `t` | Toggle timeline |
83
- | `z` | Toggle sleep mode |
100
+ | `n` | Create new agent |
84
101
  | `x` | Kill agent (double-press) |
85
102
  | `b` | Jump to next agent needing attention |
86
103
  | `h` or `?` | Show all shortcuts |
87
- | `q` | Quit |
104
+ | `q` | Quit (or detach in tmux split) |
88
105
 
89
106
  See the [TUI Guide](docs/tui-guide.md) for all keyboard shortcuts.
90
107
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "overcode"
7
- version = "0.2.6"
7
+ version = "0.3.0"
8
8
  description = "A supervisor for managing multiple Claude Code instances in tmux"
9
9
  authors = [
10
10
  {name = "Mike Bond"}
@@ -54,6 +54,14 @@ class ClaudeConfigEditor:
54
54
  self.path.parent.mkdir(parents=True, exist_ok=True)
55
55
  self.path.write_text(json.dumps(settings, indent=2) + "\n")
56
56
 
57
+ def _modify_settings(self, mutator_fn):
58
+ """Load settings, deepcopy, apply mutator_fn, save. Returns mutator's result."""
59
+ settings = self.load()
60
+ settings = copy.deepcopy(settings)
61
+ result = mutator_fn(settings)
62
+ self.save(settings)
63
+ return result
64
+
57
65
  def has_hook(self, event: str, command: str) -> bool:
58
66
  """Check if a command hook exists for the given event."""
59
67
  settings = self.load()
@@ -68,25 +76,20 @@ class ClaudeConfigEditor:
68
76
 
69
77
  Returns True if the hook was added, False if it already exists.
70
78
  """
71
- settings = self.load()
72
- # Check existing
73
- for entry in settings.get("hooks", {}).get(event, []):
74
- for hook in entry.get("hooks", []):
75
- if hook.get("command") == command:
76
- return False
77
-
78
- updated = copy.deepcopy(settings)
79
- if "hooks" not in updated:
80
- updated["hooks"] = {}
81
- if event not in updated["hooks"]:
82
- updated["hooks"][event] = []
83
-
84
- updated["hooks"][event].append({
85
- "matcher": matcher,
86
- "hooks": [{"type": "command", "command": command}],
87
- })
79
+ if self.has_hook(event, command):
80
+ return False
88
81
 
89
- self.save(updated)
82
+ def _add(settings):
83
+ if "hooks" not in settings:
84
+ settings["hooks"] = {}
85
+ if event not in settings["hooks"]:
86
+ settings["hooks"][event] = []
87
+ settings["hooks"][event].append({
88
+ "matcher": matcher,
89
+ "hooks": [{"type": "command", "command": command}],
90
+ })
91
+
92
+ self._modify_settings(_add)
90
93
  return True
91
94
 
92
95
  def remove_hook(self, event: str, command: str) -> bool:
@@ -112,18 +115,14 @@ class ClaudeConfigEditor:
112
115
  if index_to_remove is None:
113
116
  return False
114
117
 
115
- updated = copy.deepcopy(settings)
116
- del updated["hooks"][event][index_to_remove]
117
-
118
- # Clean up empty event array
119
- if not updated["hooks"][event]:
120
- del updated["hooks"][event]
121
-
122
- # Clean up empty hooks dict
123
- if not updated["hooks"]:
124
- del updated["hooks"]
118
+ def _remove(settings):
119
+ del settings["hooks"][event][index_to_remove]
120
+ if not settings["hooks"][event]:
121
+ del settings["hooks"][event]
122
+ if not settings["hooks"]:
123
+ del settings["hooks"]
125
124
 
126
- self.save(updated)
125
+ self._modify_settings(_remove)
127
126
  return True
128
127
 
129
128
  def list_hooks_matching(self, command_prefix: str) -> list[tuple[str, str]]:
@@ -147,13 +146,14 @@ class ClaudeConfigEditor:
147
146
  if tool_pattern in allow_list:
148
147
  return False
149
148
 
150
- updated = copy.deepcopy(settings)
151
- if "permissions" not in updated:
152
- updated["permissions"] = {}
153
- if "allow" not in updated["permissions"]:
154
- updated["permissions"]["allow"] = []
155
- updated["permissions"]["allow"].append(tool_pattern)
156
- self.save(updated)
149
+ def _add(settings):
150
+ if "permissions" not in settings:
151
+ settings["permissions"] = {}
152
+ if "allow" not in settings["permissions"]:
153
+ settings["permissions"]["allow"] = []
154
+ settings["permissions"]["allow"].append(tool_pattern)
155
+
156
+ self._modify_settings(_add)
157
157
  return True
158
158
 
159
159
  def remove_permission(self, tool_pattern: str) -> bool:
@@ -163,18 +163,14 @@ class ClaudeConfigEditor:
163
163
  if tool_pattern not in allow_list:
164
164
  return False
165
165
 
166
- updated = copy.deepcopy(settings)
167
- updated["permissions"]["allow"].remove(tool_pattern)
168
-
169
- # Clean up empty allow list
170
- if not updated["permissions"]["allow"]:
171
- del updated["permissions"]["allow"]
172
-
173
- # Clean up empty permissions dict
174
- if not updated["permissions"]:
175
- del updated["permissions"]
166
+ def _remove(settings):
167
+ settings["permissions"]["allow"].remove(tool_pattern)
168
+ if not settings["permissions"]["allow"]:
169
+ del settings["permissions"]["allow"]
170
+ if not settings["permissions"]:
171
+ del settings["permissions"]
176
172
 
177
- self.save(updated)
173
+ self._modify_settings(_remove)
178
174
  return True
179
175
 
180
176
  def list_permissions_matching(self, prefix: str) -> list[str]:
@@ -0,0 +1,38 @@
1
+ """
2
+ Session ID ownership guard for Claude Code sessions.
3
+
4
+ Prevents cross-contamination when multiple agents share the same working
5
+ directory by checking that a discovered sessionId isn't already owned by
6
+ another agent.
7
+
8
+ The primary mechanism is --session-id prescribed at launch (#373).
9
+ This module provides the ownership guard used by sync_session_id's
10
+ history.jsonl fallback for post-/clear detection.
11
+ """
12
+
13
+
14
+ def is_session_id_owned_by_others(
15
+ session_id: str,
16
+ own_agent_id: str,
17
+ all_sessions: list,
18
+ ) -> bool:
19
+ """Check if a Claude session ID is already owned by another agent.
20
+
21
+ Prevents cross-contamination when the directory-based lookup discovers
22
+ a sessionId that belongs to a different agent.
23
+
24
+ Args:
25
+ session_id: The Claude sessionId to check.
26
+ own_agent_id: The overcode agent ID doing the check.
27
+ all_sessions: All active overcode sessions to check against.
28
+
29
+ Returns:
30
+ True if another agent already owns this sessionId.
31
+ """
32
+ for session in all_sessions:
33
+ if session.id == own_agent_id:
34
+ continue
35
+ owned_ids = getattr(session, 'claude_session_ids', None) or []
36
+ if session_id in owned_ids:
37
+ return True
38
+ return False
@@ -21,6 +21,7 @@ from . import monitoring # noqa: F401
21
21
  from . import daemon # noqa: F401
22
22
  from . import sister # noqa: F401
23
23
  from . import config # noqa: F401
24
+ from . import split # noqa: F401
24
25
 
25
26
 
26
27
  def main():