Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
e066f2a
feat(herdr): add socket API client
jmvbambico Oct 9, 2026
4a31c84
feat(og): add og herdr bridge command
jmvbambico Oct 9, 2026
6d8454e
feat(herdr): add Omnigent session watcher
jmvbambico Oct 9, 2026
ced3382
fix(herdr): bind the fake server outside tmp_path
jmvbambico Oct 9, 2026
ad8554d
Merge branch 'feature/herdr-socket-client' into integration/herdr-bridge
jmvbambico Oct 9, 2026
dadb5c7
Merge branch 'feature/herdr-session-watcher' into integration/herdr-b…
jmvbambico Oct 9, 2026
dd7c8d3
Merge branch 'feature/og-herdr-command' into integration/herdr-bridge
jmvbambico Oct 9, 2026
06b1033
docs(herdr): record the herdr bridge findings and limits
jmvbambico Oct 9, 2026
dc95043
test(og): prove the herdr bridge imports its siblings lazily
jmvbambico Oct 9, 2026
6996047
Merge branch 'feature/og-herdr-command' into integration/herdr-bridge
jmvbambico Oct 9, 2026
9699aa1
fix(herdr): recover from a herdr call that fails part-way through one…
jmvbambico Oct 9, 2026
439ea73
test(herdr): make the aliasing test actually fail without the copy
jmvbambico Oct 9, 2026
b22f6b7
Merge branch 'feature/fix-bridge-recovery' into integration/herdr-bridge
jmvbambico Oct 9, 2026
0bca341
Merge branch 'feature/fix-watch-tests' into integration/herdr-bridge
jmvbambico Oct 9, 2026
20a09b6
fix(herdr): make removal not_found per-call and clean partial creates
jmvbambico Oct 9, 2026
6f67ee3
fix(herdr): one connection per request, real subscribe params, real e…
jmvbambico Oct 9, 2026
2e5ddc0
Merge branch 'feature/fix-client-oneshot' into integration/herdr-bridge
jmvbambico Oct 9, 2026
0ddd733
Merge branch 'feature/fix-bridge-removal' into integration/herdr-bridge
jmvbambico Oct 9, 2026
c2ae8f7
fix(herdr-watch): survive poll errors, bound the SSE buffers, match t…
jmvbambico Oct 9, 2026
39d569f
Merge branch 'feature/fix-watch-resilience' into integration/herdr-br…
jmvbambico Oct 9, 2026
16599f9
fix(herdr-client): drop the types= alias; it built unsendable requests
jmvbambico Oct 9, 2026
0df2343
Merge branch 'feature/fix-drop-types-alias' into integration/herdr-br…
jmvbambico Oct 9, 2026
0f610f2
docs(herdr): record what the socket actually does, measured
jmvbambico Oct 9, 2026
94a840f
fix(herdr): open panes in the bridge's cwd, not a nonexistent session…
jmvbambico Oct 9, 2026
5f556e1
fix(herdr-watch): build on the measured API shape, not the guessed one
jmvbambico Oct 9, 2026
60d1d5d
fix(herdr-watch): a truncated listing may not manufacture removals
jmvbambico Oct 9, 2026
e2cab60
Merge branch 'feature/fix-watch-api-shape' into integration/herdr-bridge
jmvbambico Oct 9, 2026
94308d9
Merge branch 'feature/fix-bridge-cwd' into integration/herdr-bridge
jmvbambico Oct 9, 2026
f7e914e
docs(herdr): correct the API contract I documented from the wrong source
jmvbambico Oct 9, 2026
ac0856c
fix(herdr-watch): retire what was fetched, stop dispatching half a frame
jmvbambico Oct 9, 2026
21adb0c
Merge branch 'feature/fix-watch-api-shape' into integration/herdr-bridge
jmvbambico Oct 9, 2026
1a0e130
docs(herdr): record the residuals the truncation work leaves behind
jmvbambico Oct 9, 2026
0eac251
test: make the suite hermetic against inherited PYTHONPATH
jmvbambico Oct 10, 2026
24fc68d
fix(herdr-watch): lose no notice, and stop retrying bugs
jmvbambico Oct 10, 2026
7903a9e
Merge branch 'feature/fix-watch-judgement' into integration/herdr-bridge
jmvbambico Oct 10, 2026
c92ede0
fix(herdr): open panes in the session's own directory
jmvbambico Oct 10, 2026
b12471b
Merge branch 'feature/fix-session-workspace' into integration/herdr-b…
jmvbambico Oct 10, 2026
30e50d4
docs(herdr): correct the claim that a session has no directory
jmvbambico Oct 10, 2026
6b55ec4
fix(herdr): send the wire contract herdr actually has, and check it
jmvbambico Oct 10, 2026
618e28e
Merge branch 'feature/fix-client-schema' into integration/herdr-bridge
jmvbambico Oct 10, 2026
7c840db
docs(herdr): stop naming pane.run as a method, record the schema guard
jmvbambico Oct 10, 2026
97b3edd
docs(herdr): correct the pane.run claim in _setup_pane
jmvbambico Oct 10, 2026
8e3818b
Merge branch 'feature/fix-stale-comments' into integration/herdr-bridge
jmvbambico Oct 10, 2026
63cfc02
fix(herdr): name the server in the attach command, and skip dead runners
jmvbambico Oct 10, 2026
b88f247
Merge branch 'feature/fix-attach-invocation' into integration/herdr-b…
jmvbambico Oct 10, 2026
573414d
feat(herdr): a workspace per ROOT session, its sub-agents as tabs ins…
jmvbambico Oct 10, 2026
9c06528
Merge branch 'feature/space-per-root' into integration/herdr-bridge
jmvbambico Oct 10, 2026
f316433
docs(mux): spec the og start <mux> launcher, adoption, and og agents
jmvbambico Oct 10, 2026
f6f8bf3
Merge branch 'docs/mux-launcher-spec' into integration/herdr-bridge
jmvbambico Oct 10, 2026
369279f
docs(mux): resolve the three open decisions
jmvbambico Oct 10, 2026
ec6a815
docs(readme): add Supported terminal multiplexers
jmvbambico Oct 10, 2026
7d6bd32
feat(agents): a terminal view of the Omnigent session tree
jmvbambico Oct 10, 2026
fd6c3b8
feat(herdr): state file v2, and the bridge adopts instead of duplicating
jmvbambico Oct 10, 2026
933fc06
Merge branch 'feature/feat-mux-state' into integration/herdr-bridge
jmvbambico Oct 10, 2026
6e272e8
Merge branch 'feature/feat-og-agents' into integration/herdr-bridge
jmvbambico Oct 10, 2026
02d7bfe
feat(mux): multiplexer catalog, detection, and the herdr pane question
jmvbambico Oct 10, 2026
d9532f3
Merge branch 'feature/feat-mux-registry' into integration/herdr-bridge
jmvbambico Oct 10, 2026
1763101
fix(mux): dead block, watcher private, and the workspace.rename guard
jmvbambico Oct 10, 2026
ea5a776
Merge branch 'feature/feat-mux-tidy' into integration/herdr-bridge
jmvbambico Oct 10, 2026
ffaf21f
feat(herdr): og start herdr — open the session in a herdr space
jmvbambico Oct 10, 2026
054328f
Merge branch 'feature/feat-mux-launcher' into integration/herdr-bridge
jmvbambico Oct 10, 2026
df9beba
test(mux): guard the start-args mux strip and the og help block
jmvbambico Oct 10, 2026
6e87581
Merge branch 'feature/feat-mux-parse-tests' into integration/herdr-br…
jmvbambico Oct 10, 2026
79e4aac
Merge branch 'fix/tests-pythonpath-isolation' into integration/herdr-…
jmvbambico Oct 10, 2026
eacf890
fix(herdr): start the bridge, keep the browser shut, split 80/20
jmvbambico Oct 10, 2026
3043397
Merge branch 'feature/fix-launch-findings' into integration/herdr-bridge
jmvbambico Oct 10, 2026
407475c
fix(og): print the access banner from `og chat` too
jmvbambico Oct 10, 2026
fcc4c12
Merge branch 'feature/fix-chat-access' into integration/herdr-bridge
jmvbambico Oct 10, 2026
67cad1e
feat(og agents): add an on-demand access panel (QR + URL)
jmvbambico Oct 10, 2026
9ec27f4
Merge branch 'feature/feat-agents-access' into integration/herdr-bridge
jmvbambico Oct 10, 2026
d68c888
fix(og agents): validate the tunnel cache's pid before trusting it
jmvbambico Oct 10, 2026
85bf1e1
Merge branch 'feature/feat-agents-access' into integration/herdr-bridge
jmvbambico Oct 10, 2026
b902c15
fix(herdr): close the duplicate-space race, keep the browser shut, wi…
jmvbambico Oct 10, 2026
ef2bdd9
fix(herdr): suppress the pane browser with BROWSER, not a global conf…
jmvbambico Oct 10, 2026
a11aa9c
Merge branch 'feature/fix-adoboflix' into integration/herdr-bridge
jmvbambico Oct 10, 2026
3ff0e4f
feat(og agents): rebuild the view on the B1 design, and fix two bugs …
jmvbambico Oct 11, 2026
e0b750c
Merge branch 'feature/feat-agents-b1' into integration/herdr-bridge
jmvbambico Oct 11, 2026
99ebc68
docs(proto): keep the TUI variant prototypes that chose the design
jmvbambico Oct 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ tested distro). Native Windows — PowerShell, cmd, Git Bash — is not supporte
| `ngrok` | only for `og start tunneled` on the default provider: a public URL so you can drive a run from outside your network. A *reserved domain* keeps invite links and session cookies working across restarts. |
| `ssh` | only for `og start tunneled --use tunnl.gg`: that provider *is* an ssh reverse tunnel, so there is nothing to install on macOS, Linux or Windows 10+. No account either. |
| `qrencode` | prints the tunnel URL as a QR block |
| `herdr` | only for `og start herdr`: runs the orchestrator inside [herdr](https://herdr.dev/), one space per session with each delegated worker as a tab. Without it `og start herdr` says so and starts normally; nothing else changes. |

**At least one coding CLI.** Run `./install.sh --check` to see what you have.

Expand Down Expand Up @@ -279,6 +280,50 @@ recovered exactly that way. See

---

## Supported terminal multiplexers

`og start <mux>` runs the orchestrator inside a terminal multiplexer: one space
per Omnigent session, each delegated worker a tab inside it, and — where the
backend supports it — live agent-status badges. **og is fully usable without
one.** The multiplexer is a view, never the runtime.

`installer/registry.json` is the catalog here too, but be clear what a row
buys: **detection and listing only.** The backend code still has to exist per
multiplexer, exactly as an agent row needs a harness plugin behind it.

| Multiplexer | Session → | Worker → | Agent status | Status |
|---|---|---|---|---|
| [herdr](https://herdr.dev/) | workspace ("space") | tab | **yes** — live badges | verified against 0.9.3 |
| tmux | session | window | no — window names only | not built |

The **Agent status** column is the honest part. The backend contract is
capability-based, not lowest-common-denominator: *create, close, run, focus,
rename* are required of every backend, and *report agent state* is optional.
herdr has it, which is what puts `working` / `blocked` / `idle` beside each
agent in its sidebar. tmux has no equivalent, so a tmux backend would give you
named windows and nothing more — useful, materially less.

> **A naming hazard, if tmux is ever built.** tmux is already a **required**
> dependency (see [Requirements](#requirements)): Omnigent runs every native
> agent terminal inside its own private tmux server. A user-facing `og start
> tmux` would make the word mean two things in one tool — the invisible
> substrate agents already run in, and a window manager you look at. There is no
> technical conflict (separate servers, separate sockets), but it is a
> documentation hazard exactly where a reader is most likely to be confused.

Without a multiplexer installed, `og start herdr` warns and starts normally:

```
! herdr not found on PATH — starting without it.
Install it from https://herdr.dev/ and re-run to use spaces.
```

See [docs/HERDR.md](docs/HERDR.md) for what the herdr backend does and the
measured limits it works within, and [docs/MUX-LAUNCHER.md](docs/MUX-LAUNCHER.md)
for the launcher and `og agents`.

---

## Install

Clone it wherever you keep repos — nothing depends on the location, and the
Expand Down
425 changes: 404 additions & 21 deletions bin/og

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
import sys
from pathlib import Path

import pytest

# og_install.py is a script, not a package (see AGENTS.md's "AI-driven install"
# section — it's meant to be run via `python3 installer/og_install.py`, not
# imported as `og.installer`), so tests import it directly off sys.path
# instead of relying on a src-layout package install.
sys.path.insert(0, str(Path(__file__).parent / "installer"))


@pytest.fixture(autouse=True)
def _hermetic_pythonpath(monkeypatch):
"""Strip PYTHONPATH from every test, because og itself puts it there.

`bin/og` (see the host-daemon launch, ~line 1046) deliberately exports
`PYTHONPATH=$OG_POLICY_PATH${PYTHONPATH:+:$PYTHONPATH}` so the daemon can
import omnigent_local_policies even if the installer's .pth went stale.
That is intentional and stays. But the daemon spawns everything else --
including the coding agents it runs -- and they all inherit the value. So
anyone who runs pytest from inside an og-managed session is executing the
suite with PYTHONPATH=~/.omnigent/policies set.

That is not cosmetic. PYTHONPATH entries land on sys.path *before* any
site-packages .pth gets appended, so the developer's real policies module
shadows whatever the test just wrote. The concrete symptom, measured on
this machine: `install_pth`'s verification subprocess (og_install.py,
~line 2625) imported the real 22.6 KB ~/.omnigent/policies/
omnigent_local_policies.py instead of the fixture's stand-in, that file
does `from omnigent.policies.builtins import orchestration`, the test's
fake venv has no `omnigent` installed, so the import raised
ModuleNotFoundError and `die()` turned it into SystemExit(1). Two tests
failed. CI passed, because CI has no ~/.omnigent and no PYTHONPATH -- so
this only ever breaks for a developer who has actually installed og,
i.e. exactly the people most likely to run the suite.

Worse than red: on such a machine the .pth tests could pass for the wrong
reason, with the import they are verifying resolving through PYTHONPATH
rather than through the .pth under test. Deleting this fixture makes the
suite non-hermetic, not merely flaky.

Suite-wide rather than scoped to the two known failures: any test that
spawns a subprocess is exposed to the same contamination whether or not
it fails today. `monkeypatch` restores the original value at teardown, so
nothing leaks into a later test or out of the run.
"""
monkeypatch.delenv("PYTHONPATH", raising=False)
Loading
Loading