aegis-harness 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 (48) hide show
  1. aegis_harness-0.3.0/.gitignore +182 -0
  2. aegis_harness-0.3.0/CHANGELOG.md +103 -0
  3. aegis_harness-0.3.0/LICENSE +21 -0
  4. aegis_harness-0.3.0/PKG-INFO +205 -0
  5. aegis_harness-0.3.0/README.md +170 -0
  6. aegis_harness-0.3.0/pyproject.toml +99 -0
  7. aegis_harness-0.3.0/src/aegis/__init__.py +9 -0
  8. aegis_harness-0.3.0/src/aegis/cli.py +291 -0
  9. aegis_harness-0.3.0/src/aegis/config.py +255 -0
  10. aegis_harness-0.3.0/src/aegis/core/__init__.py +0 -0
  11. aegis_harness-0.3.0/src/aegis/core/manager.py +120 -0
  12. aegis_harness-0.3.0/src/aegis/core/session.py +170 -0
  13. aegis_harness-0.3.0/src/aegis/drivers/__init__.py +22 -0
  14. aegis_harness-0.3.0/src/aegis/drivers/acp.py +422 -0
  15. aegis_harness-0.3.0/src/aegis/drivers/base.py +35 -0
  16. aegis_harness-0.3.0/src/aegis/drivers/claude.py +115 -0
  17. aegis_harness-0.3.0/src/aegis/drivers/gemini.py +24 -0
  18. aegis_harness-0.3.0/src/aegis/drivers/opencode.py +12 -0
  19. aegis_harness-0.3.0/src/aegis/events.py +181 -0
  20. aegis_harness-0.3.0/src/aegis/init_wizard.py +365 -0
  21. aegis_harness-0.3.0/src/aegis/mcp/__init__.py +20 -0
  22. aegis_harness-0.3.0/src/aegis/mcp/bridge.py +38 -0
  23. aegis_harness-0.3.0/src/aegis/mcp/runtime.py +78 -0
  24. aegis_harness-0.3.0/src/aegis/mcp/server.py +289 -0
  25. aegis_harness-0.3.0/src/aegis/py.typed +0 -0
  26. aegis_harness-0.3.0/src/aegis/queue/__init__.py +25 -0
  27. aegis_harness-0.3.0/src/aegis/queue/inbox.py +50 -0
  28. aegis_harness-0.3.0/src/aegis/queue/jsonl.py +39 -0
  29. aegis_harness-0.3.0/src/aegis/queue/manager.py +277 -0
  30. aegis_harness-0.3.0/src/aegis/queue/schema.py +85 -0
  31. aegis_harness-0.3.0/src/aegis/render.py +51 -0
  32. aegis_harness-0.3.0/src/aegis/telegram/__init__.py +0 -0
  33. aegis_harness-0.3.0/src/aegis/telegram/bot.py +63 -0
  34. aegis_harness-0.3.0/src/aegis/telegram/format.py +27 -0
  35. aegis_harness-0.3.0/src/aegis/telegram/frontend.py +191 -0
  36. aegis_harness-0.3.0/src/aegis/tui/__init__.py +8 -0
  37. aegis_harness-0.3.0/src/aegis/tui/app.py +324 -0
  38. aegis_harness-0.3.0/src/aegis/tui/metrics.py +110 -0
  39. aegis_harness-0.3.0/src/aegis/tui/names.py +142 -0
  40. aegis_harness-0.3.0/src/aegis/tui/pane.py +424 -0
  41. aegis_harness-0.3.0/src/aegis/tui/picker.py +33 -0
  42. aegis_harness-0.3.0/src/aegis/tui/state.py +25 -0
  43. aegis_harness-0.3.0/src/aegis/tui/themes.py +106 -0
  44. aegis_harness-0.3.0/src/aegis/tui/widgets.py +99 -0
  45. aegis_harness-0.3.0/src/aegis/workflow/__init__.py +10 -0
  46. aegis_harness-0.3.0/src/aegis/workflow/decorator.py +54 -0
  47. aegis_harness-0.3.0/src/aegis/workflow/engine.py +202 -0
  48. aegis_harness-0.3.0/src/aegis/workflow/runner.py +74 -0
@@ -0,0 +1,182 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python
3
+
4
+ # Local aegis config — may hold a Telegram token; never commit
5
+ .aegis.py
6
+
7
+ # Runtime state — queue lifecycle logs + per-handle inbox logs (JSONL).
8
+ .aegis/state/
9
+
10
+ ### Python ###
11
+ # Byte-compiled / optimized / DLL files
12
+ __pycache__/
13
+ *.py[cod]
14
+ *$py.class
15
+
16
+ # C extensions
17
+ *.so
18
+
19
+ # Distribution / packaging
20
+ .Python
21
+ build/
22
+ develop-eggs/
23
+ dist/
24
+ downloads/
25
+ eggs/
26
+ .eggs/
27
+ lib/
28
+ lib64/
29
+ parts/
30
+ sdist/
31
+ var/
32
+ wheels/
33
+ share/python-wheels/
34
+ *.egg-info/
35
+ .installed.cfg
36
+ *.egg
37
+ MANIFEST
38
+
39
+ # PyInstaller
40
+ # Usually these files are written by a python script from a template
41
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
42
+ *.manifest
43
+ *.spec
44
+
45
+ # Installer logs
46
+ pip-log.txt
47
+ pip-delete-this-directory.txt
48
+
49
+ # Unit test / coverage reports
50
+ htmlcov/
51
+ .tox/
52
+ .nox/
53
+ .coverage
54
+ .coverage.*
55
+ .cache
56
+ nosetests.xml
57
+ coverage.xml
58
+ *.cover
59
+ *.py,cover
60
+ .hypothesis/
61
+ .pytest_cache/
62
+ cover/
63
+
64
+ # Translations
65
+ *.mo
66
+ *.pot
67
+
68
+ # Django stuff:
69
+ *.log
70
+ local_settings.py
71
+ db.sqlite3
72
+ db.sqlite3-journal
73
+
74
+ # Flask stuff:
75
+ instance/
76
+ .webassets-cache
77
+
78
+ # Scrapy stuff:
79
+ .scrapy
80
+
81
+ # Sphinx documentation
82
+ docs/_build/
83
+
84
+ # PyBuilder
85
+ .pybuilder/
86
+ target/
87
+
88
+ # Jupyter Notebook
89
+ .ipynb_checkpoints
90
+
91
+ # IPython
92
+ profile_default/
93
+ ipython_config.py
94
+
95
+ # pyenv
96
+ # For a library or package, you might want to ignore these files since the code is
97
+ # intended to run in multiple environments; otherwise, check them in:
98
+ # .python-version
99
+
100
+ # pipenv
101
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
102
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
103
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
104
+ # install all needed dependencies.
105
+ #Pipfile.lock
106
+
107
+ # poetry
108
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
109
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
110
+ # commonly ignored for libraries.
111
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
112
+ #poetry.lock
113
+
114
+ # pdm
115
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
116
+ #pdm.lock
117
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
118
+ # in version control.
119
+ # https://pdm.fming.dev/#use-with-ide
120
+ .pdm.toml
121
+
122
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
123
+ __pypackages__/
124
+
125
+ # Celery stuff
126
+ celerybeat-schedule
127
+ celerybeat.pid
128
+
129
+ # SageMath parsed files
130
+ *.sage.py
131
+
132
+ # Environments
133
+ .env
134
+ .venv
135
+ env/
136
+ venv/
137
+ ENV/
138
+ env.bak/
139
+ venv.bak/
140
+
141
+ # Spyder project settings
142
+ .spyderproject
143
+ .spyproject
144
+
145
+ # Rope project settings
146
+ .ropeproject
147
+
148
+ # mkdocs documentation
149
+ /site
150
+
151
+ # mypy
152
+ .mypy_cache/
153
+ .dmypy.json
154
+ dmypy.json
155
+
156
+ # Pyre type checker
157
+ .pyre/
158
+
159
+ # pytype static type analyzer
160
+ .pytype/
161
+
162
+ # Cython debug symbols
163
+ cython_debug/
164
+
165
+ # PyCharm
166
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
167
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
169
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
170
+ #.idea/
171
+
172
+ ### Python Patch ###
173
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
174
+ poetry.toml
175
+
176
+ # ruff
177
+ .ruff_cache/
178
+
179
+ # LSP config files
180
+ pyrightconfig.json
181
+
182
+ # End of https://www.toptal.com/developers/gitignore/api/python
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ All notable changes to Aegis are documented here.
4
+ The format follows Keep a Changelog; this project uses SemVer (0.x).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.3.0] - 2026-05-21
9
+
10
+ First public PyPI release as `aegis-harness`. Distribution name is
11
+ `aegis-harness`; the importable package is still `aegis`.
12
+
13
+ ### Added
14
+ - **Multi-provider parity via ACP.** Gemini and OpenCode drivers rewritten
15
+ on the official Agent Client Protocol Python SDK
16
+ (`agent-client-protocol >= 0.10`). Multi-turn, streaming, cancellation,
17
+ and per-session MCP injection are now identical across `claude-code`,
18
+ `gemini`, and `opencode`.
19
+ - **Per-provider config classes** (`ClaudeCode`, `GeminiCLI`, `OpenCode`)
20
+ in `aegis.config`. Legacy flat `Agent(harness=..., model=..., ...)`
21
+ shape still works via a back-compat validator.
22
+ - **Task queues + workflows.** `aegis_enqueue` / `aegis_task_status` MCP
23
+ tools, `QueueManager` (FIFO + max-parallel + substrate-deterministic
24
+ dispatch + JSONL replay), `InboxRouter` with universal sender tagging,
25
+ `@workflow` decorator + `WorkflowEngine` runtime, `aegis workflow
26
+ list/run` CLI, `aegis_run_workflow` MCP tool.
27
+ - **Headless mode.** `aegis serve` runs SessionManager + MCP plane without
28
+ a TUI, with an optional Telegram front-end (`/new`, `/close`,
29
+ `/interrupt`, `/<handle> …`, bare-text routing). Configured via
30
+ `telegram_token` / `telegram_chat_id` / `auto_add_to_telegram_prompt`
31
+ in `.aegis.py`. systemd unit template at `scripts/aegis-serve.service`.
32
+ - **`aegis init` wizard.** Rich-powered interactive wizard that detects
33
+ installed agent CLIs, walks through agent + queue setup, and refuses
34
+ to clobber an upstream `.aegis.py` without `--force`.
35
+ - **TUI polish.** Per-block click-to-copy with hover tooltip, inline
36
+ `WorkingIndicator` (spinner + rotating verb + elapsed timer) mounted
37
+ inside the transcript, glued `ToolUse`↔`ToolResult` blocks,
38
+ max-variety alliterating handle generation (no laureate or adjective
39
+ reuse, letter cycling).
40
+ - **OIDC release workflow.** `.github/workflows/release.yml` publishes
41
+ to PyPI on `v*` tag push using PyPI trusted publishing — no token
42
+ stored in the repo.
43
+ - **Expanded docs.** New pages for Drivers, Queues, Workflows, the MCP
44
+ plane, and an auto-generated API reference via mkdocstrings.
45
+
46
+ ### Changed
47
+ - Distribution renamed from `aegis` to `aegis-harness` (the name `aegis`
48
+ was already taken on PyPI). Import path is unchanged.
49
+ - README + docs site rewritten for the multi-provider surface; old
50
+ Phase 1/1.5/2 framing replaced with a current-capability summary.
51
+ - Removed `legacy/` (sidelined FastMCP prototype) and `notes/`
52
+ (scratch markdown). Git history preserves both.
53
+
54
+ ### Fixed
55
+ - ACP driver: workaround for an upstream SDK race in `Connection.__init__`
56
+ that was killing every Gemini/OpenCode session on startup.
57
+ - ACP driver: measure `duration_ms` locally in `send()` (the final
58
+ status line was always showing 0.0s).
59
+
60
+ ## [0.2.0] - 2026-05-18
61
+
62
+ ### Added
63
+ - MCP plane (slice 1): a shared FastMCP HTTP server owned by aegis;
64
+ spawned agents are injected strict + primed and get an `aegis_meta`
65
+ orientation tool.
66
+ - MCP plane (slice 2): `aegis_list_sessions` / `aegis_list_agents` /
67
+ `aegis_handoff` (fire-and-forget inter-agent context transfer);
68
+ per-pane self-reported handle baked into the priming so each agent
69
+ knows who it is and passes that as `from_handle`.
70
+
71
+ ### Fixed
72
+ - Driver: large `tool_result` payloads (e.g. reading a SOUL.md-sized
73
+ file) no longer silent-hang a turn. `create_subprocess_exec` now
74
+ uses a 16 MiB `StreamReader` buffer (root cause: 64 KiB default was
75
+ too small for legitimate lines), and `_pump_stdout` has a
76
+ `try/finally` so the stream-closed sentinel always fires. Tool-result
77
+ display is capped at 100 chars. Regression tests cover both
78
+ guarantees.
79
+
80
+ ## [0.1.0] - 2026-05-18
81
+
82
+ First tagged release — a usable, personal-infrastructure-grade meta-harness.
83
+
84
+ ### Added
85
+ - CLI driver: runs Claude Code via `claude -p` stream-json (bidirectional,
86
+ no log scraping); agent profiles from a Python `.aegis.py`.
87
+ - Full-screen Textual TUI replacing the line REPL.
88
+ - Multi-tab: N independent agent sessions, a sideways-scrolling tab bar,
89
+ per-tab agent profiles, an `AgentPicker` modal, generated handles
90
+ (`adjective-laureate`), cross-tab signalling (state dot + sticky `*` +
91
+ bell).
92
+ - Theme engine (Textual-native) with the default **Ink** theme; themes are
93
+ drop-in.
94
+ - Live status-line metrics: true input (incl. cache) with cached %, output,
95
+ tool calls, turn / session time; provisional while streaming, exact at
96
+ turn end.
97
+ - Lazy session start (harness spawns on first message, not tab open).
98
+ - `aegis --version`.
99
+
100
+ ### Notes
101
+ - Not general-public-ready; runs from source via `uv`, drives a local
102
+ `claude` CLI. The earlier FastMCP workflow-engine prototype is preserved
103
+ under `legacy/`, unbuilt.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alejandro Piad Morffis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: aegis-harness
3
+ Version: 0.3.0
4
+ Summary: A multi-agent meta-harness for coding agents — drives Claude Code, Gemini CLI, and OpenCode in one calm full-screen TUI.
5
+ Project-URL: Homepage, https://apiad.github.io/aegis/
6
+ Project-URL: Documentation, https://apiad.github.io/aegis/
7
+ Project-URL: Repository, https://github.com/apiad/aegis
8
+ Project-URL: Issues, https://github.com/apiad/aegis/issues
9
+ Project-URL: Changelog, https://github.com/apiad/aegis/blob/main/CHANGELOG.md
10
+ Author-email: Alejandro Piad <apiad@apiad.net>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: acp,agents,ai,claude,gemini,harness,mcp,opencode,textual,tui
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Environment :: Console :: Curses
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development
24
+ Classifier: Topic :: Terminals
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.13
27
+ Requires-Dist: agent-client-protocol>=0.10
28
+ Requires-Dist: fastmcp>=3.2.0
29
+ Requires-Dist: httpx>=0.28
30
+ Requires-Dist: pydantic>=2.12.5
31
+ Requires-Dist: rich>=14.3.3
32
+ Requires-Dist: textual>=8.2.6
33
+ Requires-Dist: typer>=0.24.1
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Aegis
37
+
38
+ > A multi-agent meta-harness for coding agents — drives Claude Code,
39
+ > Gemini CLI, and OpenCode side by side in one calm full-screen TUI.
40
+
41
+ [![CI](https://github.com/apiad/aegis/actions/workflows/ci.yml/badge.svg)](https://github.com/apiad/aegis/actions/workflows/ci.yml)
42
+ [![Docs](https://img.shields.io/badge/docs-apiad.github.io%2Faegis-blue)](https://apiad.github.io/aegis/)
43
+ [![PyPI](https://img.shields.io/pypi/v/aegis-harness.svg)](https://pypi.org/project/aegis-harness/)
44
+ [![Python](https://img.shields.io/badge/python-3.13+-blue)](https://www.python.org/)
45
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
46
+
47
+ Aegis sits **above** the harness. It drives existing coding-agent CLIs —
48
+ `claude` (Anthropic), `gemini` (Google), `opencode` (open-source) — over
49
+ their structured protocols (stream-json and ACP), parses the event
50
+ streams, and re-renders them in a calm Textual TUI where many agents run
51
+ side by side. It adds a routing + delegation plane on top: queues,
52
+ workflows, an MCP server every spawned agent talks to, and an optional
53
+ Telegram front-end.
54
+
55
+ ```
56
+ ┌ aegis ───────────────────────────────────────────────┐
57
+ │ ● 1 lucid-knuth ·opus· ● 2 wry-hopper ·gemini· * │
58
+ │ │
59
+ │ › explain the retry logic │
60
+ │ │
61
+ │ ⠹ Thinking… (3.2s) │
62
+ │ ⏺ Read(worker.py) │
63
+ │ └ ok │
64
+ │ The retry path lives in _run_turn … │
65
+ │ │
66
+ │ lucid-knuth ·opus· opus·full ↑128k (94% cached) ↓1k │
67
+ │ ───────────────────────────────────────────────────── │
68
+ │ › ask something… │
69
+ └───────────────────────────────────────────────────────┘
70
+ ```
71
+
72
+ ## Install
73
+
74
+ ```bash
75
+ pip install aegis-harness # or: uv pip install aegis-harness
76
+ ```
77
+
78
+ Requires Python 3.13+ and at least one of: `claude`, `gemini`, or
79
+ `opencode` on your `PATH`, signed-in.
80
+
81
+ ## Quickstart
82
+
83
+ ```bash
84
+ aegis init # interactive wizard — detects installed CLIs, writes .aegis.py
85
+ aegis # full-screen TUI
86
+ ```
87
+
88
+ The wizard finds whichever agent CLIs you have installed and walks you
89
+ through picking a model, permission mode, and optional queues. The
90
+ generated `.aegis.py` is plain Python — edit it freely afterwards.
91
+
92
+ ## What you get
93
+
94
+ - **Multi-provider parity** — Claude Code, Gemini, and OpenCode all
95
+ speak through aegis with the same UX (multi-turn, streaming,
96
+ cancellation, per-session MCP injection). Gemini and OpenCode use
97
+ [ACP](https://github.com/zed-industries/agent-client-protocol);
98
+ Claude uses its stream-json bidirectional protocol.
99
+ - **Multi-tab TUI** — N independent agent sessions in one terminal.
100
+ Per-tab profiles, generated alliterating handles
101
+ (`lucid-knuth`, `wry-hopper`), per-block copy-to-clipboard, an inline
102
+ spinner + rotating verb + timer while an agent works, cross-tab
103
+ signalling (state dot + sticky `*` + bell when a backgrounded agent
104
+ finishes).
105
+ - **Honest metrics** — true input (incl. cache) with cached %, output,
106
+ tool calls, per-turn and per-session timing. Provisional while
107
+ streaming, exact at turn end.
108
+ - **Queues + workflows** — first-class inter-agent delegation. Configure
109
+ queues in `.aegis.py`; any agent can call `aegis_enqueue(queue,
110
+ payload)` and get an automatic inbox callback when the worker
111
+ finishes. Write Python workflows that orchestrate multiple agents
112
+ (delegate / send / drain / spawn / close / bash) and run them via
113
+ `aegis workflow run`.
114
+ - **MCP plane** — every spawned agent gets injected with an aegis MCP
115
+ server that exposes orientation (`aegis_meta`), session listing
116
+ (`aegis_list_sessions`, `aegis_list_agents`), peer handoff
117
+ (`aegis_handoff`), and queue dispatch (`aegis_enqueue`,
118
+ `aegis_task_status`). No log scraping anywhere in the stack.
119
+ - **Headless + Telegram** — `aegis serve` runs the SessionManager and
120
+ MCP plane without a TUI, with an optional Telegram front-end so you
121
+ can drive agents from your phone.
122
+
123
+ ## Keys
124
+
125
+ | Key | Action |
126
+ |---|---|
127
+ | `Enter` | Send |
128
+ | `Ctrl+T` / `Ctrl+N` | New tab (default agent) / new tab (pick agent) |
129
+ | `Ctrl+W` | Close tab (last → quit) |
130
+ | `Ctrl+1`..`9` / `Ctrl+Tab` / `Ctrl+←→` | Switch tabs |
131
+ | `Escape` | Interrupt the active turn |
132
+ | `Click on a block` | Copy that message / tool result to clipboard |
133
+ | `Ctrl+Q` | Quit |
134
+
135
+ A backgrounded tab that finishes shows a `*` and rings the bell.
136
+
137
+ ## Configuration
138
+
139
+ `.aegis.py` is plain Python. The wizard writes one for you; here's the
140
+ shape:
141
+
142
+ ```python
143
+ from aegis import Agent, ClaudeCode, GeminiCLI, OpenCode
144
+
145
+ agents = {
146
+ "default": Agent(provider=ClaudeCode(model="opus", effort="high",
147
+ permission="auto")),
148
+ "fast": Agent(provider=GeminiCLI(model="gemini-3-flash-preview",
149
+ permission="full")),
150
+ "oss": Agent(provider=OpenCode(model="opencode/kimi-k2.6",
151
+ permission="full")),
152
+ }
153
+ default_agent = "default"
154
+
155
+ queues = {
156
+ "review": {"agent": "fast", "max_parallel": 2},
157
+ }
158
+ ```
159
+
160
+ Full reference: [Configuration](https://apiad.github.io/aegis/configuration/).
161
+
162
+ ## Headless + Telegram
163
+
164
+ `aegis serve` runs the SessionManager and MCP plane without the TUI; add
165
+ a Telegram token to drive it from your phone:
166
+
167
+ ```python
168
+ # .aegis.py
169
+ telegram_token = "…" # or set AEGIS_TELEGRAM_TOKEN
170
+ telegram_chat_id = 123456 # the single allowed chat
171
+ ```
172
+
173
+ Routing inside the chat:
174
+
175
+ - `/new [agent]` — spawn a new session
176
+ - `/close [handle]` — close a session
177
+ - `/interrupt` — interrupt the active turn
178
+ - `/<handle> text…` — one-shot to a specific session
179
+ - bare text — sent to the active session
180
+
181
+ A systemd unit template lives at `scripts/aegis-serve.service`.
182
+
183
+ ## Docs
184
+
185
+ Full documentation: **[https://apiad.github.io/aegis/](https://apiad.github.io/aegis/)**
186
+
187
+ - [Install](https://apiad.github.io/aegis/install/)
188
+ - [Usage](https://apiad.github.io/aegis/usage/)
189
+ - [Configuration](https://apiad.github.io/aegis/configuration/)
190
+ - [Drivers](https://apiad.github.io/aegis/drivers/) — Claude / Gemini / OpenCode
191
+ - [Queues](https://apiad.github.io/aegis/queues/) — inter-agent delegation
192
+ - [Workflows](https://apiad.github.io/aegis/workflows/) — Python orchestration
193
+ - [MCP plane](https://apiad.github.io/aegis/mcp/) — the tool surface
194
+ - [Architecture](https://apiad.github.io/aegis/architecture/)
195
+ - [API reference](https://apiad.github.io/aegis/api/)
196
+
197
+ ## Status
198
+
199
+ Beta. Personal-infrastructure-grade, evolves fast. Expect change before
200
+ 1.0. See the [roadmap](https://apiad.github.io/aegis/roadmap/) for
201
+ what's next.
202
+
203
+ ## License
204
+
205
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,170 @@
1
+ # Aegis
2
+
3
+ > A multi-agent meta-harness for coding agents — drives Claude Code,
4
+ > Gemini CLI, and OpenCode side by side in one calm full-screen TUI.
5
+
6
+ [![CI](https://github.com/apiad/aegis/actions/workflows/ci.yml/badge.svg)](https://github.com/apiad/aegis/actions/workflows/ci.yml)
7
+ [![Docs](https://img.shields.io/badge/docs-apiad.github.io%2Faegis-blue)](https://apiad.github.io/aegis/)
8
+ [![PyPI](https://img.shields.io/pypi/v/aegis-harness.svg)](https://pypi.org/project/aegis-harness/)
9
+ [![Python](https://img.shields.io/badge/python-3.13+-blue)](https://www.python.org/)
10
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
11
+
12
+ Aegis sits **above** the harness. It drives existing coding-agent CLIs —
13
+ `claude` (Anthropic), `gemini` (Google), `opencode` (open-source) — over
14
+ their structured protocols (stream-json and ACP), parses the event
15
+ streams, and re-renders them in a calm Textual TUI where many agents run
16
+ side by side. It adds a routing + delegation plane on top: queues,
17
+ workflows, an MCP server every spawned agent talks to, and an optional
18
+ Telegram front-end.
19
+
20
+ ```
21
+ ┌ aegis ───────────────────────────────────────────────┐
22
+ │ ● 1 lucid-knuth ·opus· ● 2 wry-hopper ·gemini· * │
23
+ │ │
24
+ │ › explain the retry logic │
25
+ │ │
26
+ │ ⠹ Thinking… (3.2s) │
27
+ │ ⏺ Read(worker.py) │
28
+ │ └ ok │
29
+ │ The retry path lives in _run_turn … │
30
+ │ │
31
+ │ lucid-knuth ·opus· opus·full ↑128k (94% cached) ↓1k │
32
+ │ ───────────────────────────────────────────────────── │
33
+ │ › ask something… │
34
+ └───────────────────────────────────────────────────────┘
35
+ ```
36
+
37
+ ## Install
38
+
39
+ ```bash
40
+ pip install aegis-harness # or: uv pip install aegis-harness
41
+ ```
42
+
43
+ Requires Python 3.13+ and at least one of: `claude`, `gemini`, or
44
+ `opencode` on your `PATH`, signed-in.
45
+
46
+ ## Quickstart
47
+
48
+ ```bash
49
+ aegis init # interactive wizard — detects installed CLIs, writes .aegis.py
50
+ aegis # full-screen TUI
51
+ ```
52
+
53
+ The wizard finds whichever agent CLIs you have installed and walks you
54
+ through picking a model, permission mode, and optional queues. The
55
+ generated `.aegis.py` is plain Python — edit it freely afterwards.
56
+
57
+ ## What you get
58
+
59
+ - **Multi-provider parity** — Claude Code, Gemini, and OpenCode all
60
+ speak through aegis with the same UX (multi-turn, streaming,
61
+ cancellation, per-session MCP injection). Gemini and OpenCode use
62
+ [ACP](https://github.com/zed-industries/agent-client-protocol);
63
+ Claude uses its stream-json bidirectional protocol.
64
+ - **Multi-tab TUI** — N independent agent sessions in one terminal.
65
+ Per-tab profiles, generated alliterating handles
66
+ (`lucid-knuth`, `wry-hopper`), per-block copy-to-clipboard, an inline
67
+ spinner + rotating verb + timer while an agent works, cross-tab
68
+ signalling (state dot + sticky `*` + bell when a backgrounded agent
69
+ finishes).
70
+ - **Honest metrics** — true input (incl. cache) with cached %, output,
71
+ tool calls, per-turn and per-session timing. Provisional while
72
+ streaming, exact at turn end.
73
+ - **Queues + workflows** — first-class inter-agent delegation. Configure
74
+ queues in `.aegis.py`; any agent can call `aegis_enqueue(queue,
75
+ payload)` and get an automatic inbox callback when the worker
76
+ finishes. Write Python workflows that orchestrate multiple agents
77
+ (delegate / send / drain / spawn / close / bash) and run them via
78
+ `aegis workflow run`.
79
+ - **MCP plane** — every spawned agent gets injected with an aegis MCP
80
+ server that exposes orientation (`aegis_meta`), session listing
81
+ (`aegis_list_sessions`, `aegis_list_agents`), peer handoff
82
+ (`aegis_handoff`), and queue dispatch (`aegis_enqueue`,
83
+ `aegis_task_status`). No log scraping anywhere in the stack.
84
+ - **Headless + Telegram** — `aegis serve` runs the SessionManager and
85
+ MCP plane without a TUI, with an optional Telegram front-end so you
86
+ can drive agents from your phone.
87
+
88
+ ## Keys
89
+
90
+ | Key | Action |
91
+ |---|---|
92
+ | `Enter` | Send |
93
+ | `Ctrl+T` / `Ctrl+N` | New tab (default agent) / new tab (pick agent) |
94
+ | `Ctrl+W` | Close tab (last → quit) |
95
+ | `Ctrl+1`..`9` / `Ctrl+Tab` / `Ctrl+←→` | Switch tabs |
96
+ | `Escape` | Interrupt the active turn |
97
+ | `Click on a block` | Copy that message / tool result to clipboard |
98
+ | `Ctrl+Q` | Quit |
99
+
100
+ A backgrounded tab that finishes shows a `*` and rings the bell.
101
+
102
+ ## Configuration
103
+
104
+ `.aegis.py` is plain Python. The wizard writes one for you; here's the
105
+ shape:
106
+
107
+ ```python
108
+ from aegis import Agent, ClaudeCode, GeminiCLI, OpenCode
109
+
110
+ agents = {
111
+ "default": Agent(provider=ClaudeCode(model="opus", effort="high",
112
+ permission="auto")),
113
+ "fast": Agent(provider=GeminiCLI(model="gemini-3-flash-preview",
114
+ permission="full")),
115
+ "oss": Agent(provider=OpenCode(model="opencode/kimi-k2.6",
116
+ permission="full")),
117
+ }
118
+ default_agent = "default"
119
+
120
+ queues = {
121
+ "review": {"agent": "fast", "max_parallel": 2},
122
+ }
123
+ ```
124
+
125
+ Full reference: [Configuration](https://apiad.github.io/aegis/configuration/).
126
+
127
+ ## Headless + Telegram
128
+
129
+ `aegis serve` runs the SessionManager and MCP plane without the TUI; add
130
+ a Telegram token to drive it from your phone:
131
+
132
+ ```python
133
+ # .aegis.py
134
+ telegram_token = "…" # or set AEGIS_TELEGRAM_TOKEN
135
+ telegram_chat_id = 123456 # the single allowed chat
136
+ ```
137
+
138
+ Routing inside the chat:
139
+
140
+ - `/new [agent]` — spawn a new session
141
+ - `/close [handle]` — close a session
142
+ - `/interrupt` — interrupt the active turn
143
+ - `/<handle> text…` — one-shot to a specific session
144
+ - bare text — sent to the active session
145
+
146
+ A systemd unit template lives at `scripts/aegis-serve.service`.
147
+
148
+ ## Docs
149
+
150
+ Full documentation: **[https://apiad.github.io/aegis/](https://apiad.github.io/aegis/)**
151
+
152
+ - [Install](https://apiad.github.io/aegis/install/)
153
+ - [Usage](https://apiad.github.io/aegis/usage/)
154
+ - [Configuration](https://apiad.github.io/aegis/configuration/)
155
+ - [Drivers](https://apiad.github.io/aegis/drivers/) — Claude / Gemini / OpenCode
156
+ - [Queues](https://apiad.github.io/aegis/queues/) — inter-agent delegation
157
+ - [Workflows](https://apiad.github.io/aegis/workflows/) — Python orchestration
158
+ - [MCP plane](https://apiad.github.io/aegis/mcp/) — the tool surface
159
+ - [Architecture](https://apiad.github.io/aegis/architecture/)
160
+ - [API reference](https://apiad.github.io/aegis/api/)
161
+
162
+ ## Status
163
+
164
+ Beta. Personal-infrastructure-grade, evolves fast. Expect change before
165
+ 1.0. See the [roadmap](https://apiad.github.io/aegis/roadmap/) for
166
+ what's next.
167
+
168
+ ## License
169
+
170
+ MIT — see [LICENSE](LICENSE).