overcode 0.2.0__tar.gz → 0.2.2__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.2.0/src/overcode.egg-info → overcode-0.2.2}/PKG-INFO +1 -1
- {overcode-0.2.0 → overcode-0.2.2}/pyproject.toml +2 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/bundled_skills.py +34 -0
- overcode-0.2.2/src/overcode/cli/__init__.py +32 -0
- overcode-0.2.2/src/overcode/cli/__main__.py +5 -0
- overcode-0.2.2/src/overcode/cli/_shared.py +121 -0
- overcode-0.2.2/src/overcode/cli/agent.py +884 -0
- overcode-0.2.2/src/overcode/cli/budget.py +147 -0
- overcode-0.2.2/src/overcode/cli/config.py +157 -0
- overcode-0.2.2/src/overcode/cli/daemon.py +220 -0
- overcode-0.2.2/src/overcode/cli/hooks.py +123 -0
- overcode-0.2.2/src/overcode/cli/monitoring.py +566 -0
- overcode-0.2.2/src/overcode/cli/perms.py +147 -0
- overcode-0.2.2/src/overcode/cli/sister.py +163 -0
- overcode-0.2.2/src/overcode/cli/skills.py +149 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/config.py +42 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/daemon_logging.py +1 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/data_export.py +2 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/follow_mode.py +0 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/history_reader.py +69 -75
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/hook_handler.py +5 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/hook_status_detector.py +59 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/implementations.py +1 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/launcher.py +54 -5
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/logging_config.py +0 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/monitor_daemon.py +282 -213
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/monitor_daemon_core.py +126 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/monitor_daemon_state.py +11 -169
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/presence_logger.py +39 -11
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/session_manager.py +16 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/settings.py +23 -3
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/sister_poller.py +46 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/status_constants.py +22 -5
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/status_detector.py +15 -4
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/status_detector_factory.py +0 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/status_patterns.py +105 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/summary_columns.py +317 -55
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/summary_groups.py +4 -4
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/supervisor_daemon.py +44 -79
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/supervisor_daemon_core.py +101 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/testing/renderer.py +0 -3
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/testing/tui_eye.py +1 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/time_context.py +4 -4
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui.py +325 -179
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui.tcss +16 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/daemon.py +18 -2
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/input.py +3 -3
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/navigation.py +1 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/session.py +28 -3
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/view.py +20 -4
- overcode-0.2.2/src/overcode/tui_helpers.py +660 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_logic.py +155 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_render.py +5 -8
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/__init__.py +2 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/command_bar.py +227 -77
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/daemon_status_bar.py +42 -16
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/help_overlay.py +4 -0
- overcode-0.2.2/src/overcode/tui_widgets/new_agent_defaults_modal.py +131 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/session_summary.py +69 -68
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/status_timeline.py +8 -8
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/summary_config_modal.py +0 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/usage_monitor.py +29 -12
- overcode-0.2.2/src/overcode/web/__init__.py +0 -0
- overcode-0.2.0/src/overcode/web_templates.py → overcode-0.2.2/src/overcode/web/templates/analytics.html +2 -569
- overcode-0.2.2/src/overcode/web/templates/dashboard.html +553 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/web_api.py +33 -8
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/web_server.py +18 -18
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/web_server_runner.py +3 -1
- overcode-0.2.2/src/overcode/web_templates.py +23 -0
- {overcode-0.2.0 → overcode-0.2.2/src/overcode.egg-info}/PKG-INFO +1 -1
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode.egg-info/SOURCES.txt +16 -2
- overcode-0.2.0/src/overcode/cli.py +0 -2449
- overcode-0.2.0/src/overcode/tui_formatters.py +0 -235
- overcode-0.2.0/src/overcode/tui_helpers.py +0 -357
- {overcode-0.2.0 → overcode-0.2.2}/LICENSE +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/MANIFEST.in +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/README.md +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/setup.cfg +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/__init__.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/claude_config.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/daemon_claude_skill.md +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/daemon_utils.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/dependency_check.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/exceptions.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/interfaces.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/mocks.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/notifier.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/pid_utils.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/protocols.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/sister_controller.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/standing_instructions.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/status_history.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/summarizer_client.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/summarizer_component.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/supervisor_layout.sh +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/testing/__init__.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/testing/tmux_driver.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/testing/tui_eye_skill.md +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tmux_manager.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tmux_utils.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_actions/__init__.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/daemon_panel.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/fullscreen_preview.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/tui_widgets/preview_pane.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/web_chartjs.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode/web_control_api.py +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode.egg-info/dependency_links.txt +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode.egg-info/entry_points.txt +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode.egg-info/requires.txt +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/src/overcode.egg-info/top_level.txt +0 -0
- {overcode-0.2.0 → overcode-0.2.2}/tests/test_e2e_multi_agent_jokes.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "overcode"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "A supervisor for managing multiple Claude Code instances in tmux"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Mike Bond"}
|
|
@@ -68,7 +68,7 @@ tui-eye = "overcode.testing.tui_eye:main"
|
|
|
68
68
|
where = ["src"]
|
|
69
69
|
|
|
70
70
|
[tool.setuptools.package-data]
|
|
71
|
-
overcode = ["*.md", "*.sh", "*.tcss"]
|
|
71
|
+
overcode = ["*.md", "*.sh", "*.tcss", "web/templates/*.html"]
|
|
72
72
|
|
|
73
73
|
[tool.black]
|
|
74
74
|
line-length = 100
|
|
@@ -5,6 +5,8 @@ Skills are installed as directories with a SKILL.md entry point, following
|
|
|
5
5
|
the Claude Code skill format. Each skill has a description and content field.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
8
10
|
# Skill names that were renamed — installer removes these on install
|
|
9
11
|
DEPRECATED_SKILL_NAMES = ["delegation"]
|
|
10
12
|
|
|
@@ -28,6 +30,8 @@ Overcode manages multiple Claude Code agent sessions in tmux.
|
|
|
28
30
|
# Launch
|
|
29
31
|
overcode launch -n <name> [-d <path>] [-p "<prompt>"] [--follow] [--bypass-permissions]
|
|
30
32
|
overcode launch -n <name> --follow --oversight-timeout 5m -p "... When done: overcode report --status success"
|
|
33
|
+
overcode launch -n <name> --allowed-tools "Read,Glob,Grep" --skip-permissions
|
|
34
|
+
overcode launch -n <name> --claude-arg "--model haiku" --claude-arg "--effort low"
|
|
31
35
|
|
|
32
36
|
# Monitor
|
|
33
37
|
overcode list [name] [--show-done]
|
|
@@ -165,6 +169,26 @@ overcode budget set child-agent 3.00 # Set directly
|
|
|
165
169
|
|
|
166
170
|
Exceeded budget = heartbeats and supervisor stop, agent winds down naturally.
|
|
167
171
|
|
|
172
|
+
## Tool Restrictions
|
|
173
|
+
|
|
174
|
+
Scope agent capabilities with `--allowed-tools` for safety:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Read-only agent — cannot modify files
|
|
178
|
+
overcode launch -n safe-reader --follow --allowed-tools "Read,Glob,Grep" \\
|
|
179
|
+
-p "Analyze the codebase. Do NOT modify files. When done: overcode report --status success"
|
|
180
|
+
|
|
181
|
+
# Code-only agent — no shell access
|
|
182
|
+
overcode launch -n coder --follow --allowed-tools "Read,Write,Edit,Glob,Grep" --skip-permissions \\
|
|
183
|
+
-p "Refactor auth module. When done: overcode report --status success"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Pass arbitrary Claude CLI flags with `--claude-arg` (repeatable):
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
overcode launch -n fast --claude-arg "--model haiku" --claude-arg "--effort low" -p "Quick review"
|
|
190
|
+
```
|
|
191
|
+
|
|
168
192
|
## Rules
|
|
169
193
|
|
|
170
194
|
- Parent auto-detected from `OVERCODE_SESSION_NAME` \u2014 no `--parent` needed inside an overcode agent
|
|
@@ -173,3 +197,13 @@ Exceeded budget = heartbeats and supervisor stop, agent winds down naturally.
|
|
|
173
197
|
""",
|
|
174
198
|
},
|
|
175
199
|
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def any_skills_stale() -> bool:
|
|
203
|
+
"""Check if any installed skills are outdated vs bundled versions."""
|
|
204
|
+
base = Path.home() / ".claude" / "skills"
|
|
205
|
+
for name, skill in OVERCODE_SKILLS.items():
|
|
206
|
+
skill_file = base / name / "SKILL.md"
|
|
207
|
+
if skill_file.exists() and skill_file.read_text() != skill["content"]:
|
|
208
|
+
return True
|
|
209
|
+
return False
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI interface for Overcode using Typer.
|
|
3
|
+
|
|
4
|
+
This package was split from a single cli.py module. All public names
|
|
5
|
+
are re-exported here for backward compatibility.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Import shared state (apps, options, utilities) — must come first
|
|
9
|
+
from ._shared import app, main_callback, _parse_duration, SessionOption # noqa: F401
|
|
10
|
+
|
|
11
|
+
# Re-export for backward compat (tests patch overcode.cli.ClaudeLauncher)
|
|
12
|
+
from ..launcher import ClaudeLauncher # noqa: F401
|
|
13
|
+
|
|
14
|
+
# Import submodules to register their commands with the Typer apps
|
|
15
|
+
from . import agent # noqa: F401
|
|
16
|
+
from . import budget # noqa: F401
|
|
17
|
+
from . import hooks # noqa: F401
|
|
18
|
+
from . import skills # noqa: F401
|
|
19
|
+
from . import perms # noqa: F401
|
|
20
|
+
from . import monitoring # noqa: F401
|
|
21
|
+
from . import daemon # noqa: F401
|
|
22
|
+
from . import sister # noqa: F401
|
|
23
|
+
from . import config # noqa: F401
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main():
|
|
27
|
+
"""Main entry point for the CLI."""
|
|
28
|
+
app()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared CLI state: Typer apps, console, options, and utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
# Main app
|
|
11
|
+
app = typer.Typer(
|
|
12
|
+
name="overcode",
|
|
13
|
+
help="Manage and supervise Claude Code agents",
|
|
14
|
+
no_args_is_help=False,
|
|
15
|
+
invoke_without_command=True,
|
|
16
|
+
rich_markup_mode="rich",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Monitor daemon subcommand group
|
|
21
|
+
monitor_daemon_app = typer.Typer(
|
|
22
|
+
name="monitor-daemon",
|
|
23
|
+
help="Manage the Monitor Daemon (metrics/state tracking)",
|
|
24
|
+
no_args_is_help=False,
|
|
25
|
+
invoke_without_command=True,
|
|
26
|
+
)
|
|
27
|
+
app.add_typer(monitor_daemon_app, name="monitor-daemon")
|
|
28
|
+
|
|
29
|
+
# Supervisor daemon subcommand group
|
|
30
|
+
supervisor_daemon_app = typer.Typer(
|
|
31
|
+
name="supervisor-daemon",
|
|
32
|
+
help="Manage the Supervisor Daemon (Claude orchestration)",
|
|
33
|
+
no_args_is_help=False,
|
|
34
|
+
invoke_without_command=True,
|
|
35
|
+
)
|
|
36
|
+
app.add_typer(supervisor_daemon_app, name="supervisor-daemon")
|
|
37
|
+
|
|
38
|
+
# Hooks subcommand group
|
|
39
|
+
hooks_app = typer.Typer(
|
|
40
|
+
name="hooks",
|
|
41
|
+
help="Manage Claude Code hook integration.",
|
|
42
|
+
no_args_is_help=True,
|
|
43
|
+
)
|
|
44
|
+
app.add_typer(hooks_app, name="hooks")
|
|
45
|
+
|
|
46
|
+
# Skills subcommand group
|
|
47
|
+
skills_app = typer.Typer(
|
|
48
|
+
name="skills",
|
|
49
|
+
help="Manage Claude Code skill files.",
|
|
50
|
+
no_args_is_help=True,
|
|
51
|
+
)
|
|
52
|
+
app.add_typer(skills_app, name="skills")
|
|
53
|
+
|
|
54
|
+
# Perms subcommand group
|
|
55
|
+
perms_app = typer.Typer(
|
|
56
|
+
name="perms",
|
|
57
|
+
help="Manage Claude Code tool permissions for overcode commands.",
|
|
58
|
+
no_args_is_help=True,
|
|
59
|
+
)
|
|
60
|
+
app.add_typer(perms_app, name="perms")
|
|
61
|
+
|
|
62
|
+
# Budget subcommand group (#244)
|
|
63
|
+
budget_app = typer.Typer(
|
|
64
|
+
name="budget",
|
|
65
|
+
help="Manage agent cost budgets.",
|
|
66
|
+
no_args_is_help=True,
|
|
67
|
+
)
|
|
68
|
+
app.add_typer(budget_app, name="budget")
|
|
69
|
+
|
|
70
|
+
# Sister subcommand group
|
|
71
|
+
sister_app = typer.Typer(
|
|
72
|
+
name="sister",
|
|
73
|
+
help="Manage sister instances for cross-machine monitoring.",
|
|
74
|
+
no_args_is_help=False,
|
|
75
|
+
invoke_without_command=True,
|
|
76
|
+
)
|
|
77
|
+
app.add_typer(sister_app, name="sister")
|
|
78
|
+
|
|
79
|
+
# Config subcommand group
|
|
80
|
+
config_app = typer.Typer(
|
|
81
|
+
name="config",
|
|
82
|
+
help="Manage configuration",
|
|
83
|
+
no_args_is_help=False,
|
|
84
|
+
invoke_without_command=True,
|
|
85
|
+
)
|
|
86
|
+
app.add_typer(config_app, name="config")
|
|
87
|
+
|
|
88
|
+
# Console for rich output
|
|
89
|
+
console = Console()
|
|
90
|
+
|
|
91
|
+
# Global session option (hidden advanced usage)
|
|
92
|
+
SessionOption = Annotated[
|
|
93
|
+
str,
|
|
94
|
+
typer.Option(
|
|
95
|
+
"--session",
|
|
96
|
+
hidden=True,
|
|
97
|
+
help="Tmux session name for agents",
|
|
98
|
+
),
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _parse_duration(s: str) -> float:
|
|
103
|
+
"""Parse a duration string like '5m', '1h', '30s', '90' into seconds."""
|
|
104
|
+
s = s.strip().lower()
|
|
105
|
+
if s.endswith('s'):
|
|
106
|
+
return float(s[:-1])
|
|
107
|
+
elif s.endswith('m'):
|
|
108
|
+
return float(s[:-1]) * 60
|
|
109
|
+
elif s.endswith('h'):
|
|
110
|
+
return float(s[:-1]) * 3600
|
|
111
|
+
else:
|
|
112
|
+
return float(s)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@app.callback(invoke_without_command=True)
|
|
116
|
+
def main_callback(ctx: typer.Context):
|
|
117
|
+
"""Launch the TUI monitor when no command is given."""
|
|
118
|
+
if ctx.invoked_subcommand is None:
|
|
119
|
+
from ..tui import run_tui
|
|
120
|
+
|
|
121
|
+
run_tui("agents")
|